python中的装饰器怎么运行_Python 装饰器入门(上)

翻译前想说的话:

这是一篇介绍python装饰器的文章,对比之前看到的类似介绍装饰器的文章,个人认为无人可出其右,文章由浅到深,由函数介绍到装饰器的高级应用,每个介绍必有例子说明。文章太长,看完原文后我计划按照文章作者的划分,将分为两章翻出来和大家分享,如果你觉得干的还不错,就点个赞吧.

目录:

函数

一等对象

内部函数

从函数中返回函数

简单装饰器

语法糖

复用装饰器

装饰器传参

从装饰器返回值

你是谁?

一些现实中的例子

时间函数

调试代码

给代码降速

注册插件

用户是否登录?

有想象力的装饰器

装饰类

嵌套的装饰器

带参数的装饰器

Both

Please, But Never Mind the Bread

这句话开始我不知道怎么翻,直到我看到了维尼熊......,请在这里www.google.com检索Winnie the Pooh  Both

Please, But Never Mind the Bread

有状态的装饰器

类装饰器

更多现实中的例子

代码降速,重新访问

创建单例模式

缓存返回值

添加单元信息

验证JSON

正文开始:

在本次的装饰器教程中,将介绍何为装饰器以及如何创建和使用它们,装饰器提供了简单的语法来调用高阶函数。

从定义上讲,装饰器是一个函数,它接收另一个函数作为参数并且扩展它的功能,但不会显式的去修改它

说起来可能会让人觉得难理解,但它(装饰器)确实不会这么做,特别是一会你会看到一些装饰器如何工作的例子

函数

在理解装饰器之前,你首先需要理解函数如何工作。函数会基于给定的参数返回值。这里有一个非常简单的例子:

>>> defadd_one(number):

...return number + 1

>>> add_one(2)3

通常情况下,函数在python中也会有其它功效而不是仅仅接收输入并返回输出。print()函数是一个例子。在控制台输出的时候它会返回None(1),然而,为了理解装饰器,

将函数认为是接收参数并返回值就足够了

注意:在面向函数编程,你几乎只会使用纯函数,不会有其它功能,然而python不是一个纯函数式语言,python支持许多函数式编程概念,包括一等对象

一等对象

在python中,函数是一等对象,意思是函数可以作为参数被传递,就像其它的对象(string,int,fload,list和其它),思考下面的三个函数

defsay_hello(name):return f"Hello {name}"

defbe_awesome(name):return f"Yo {name}, together we are the awesomest!"

defgreet_bob(greeter_func):return greeter_func("Bob")

在这里,say_hello()和be_awsone()是常规函数,接收一个name参数返回一个字符串,然而greet_bob()函数,接收一个函数作为他的参数,我们可以将say_hello()或者be_awesome()函数传递给它

>>>greet_bob(say_hello)'Hello Bob'

>>>greet_bob(be_awesome)'Yo Bob, together we are the awesomest!'

注意greet_bob(say_hello) 涉及到两个函数,但是不同的是:greet_bob()和say_hello,say_hello函数并没有使用(),代表只传递了对函数的引用,函数没有运行,greet_bob()函数,是使用了括号,所以它会被正常调用

内部函数

在函数内定义函数是被允许的。这类函数被称为内部函数,这里有一个函数和两个内函数的例子

defparent():print("Printing from the parent() function")deffirst_child():print("Printing from the first_child() function")defsecond_child():print("Printing from the second_child() function")

second_child()

first_child()

当你调用parent()的时候会发生什么? 请考虑一分钟。会出现下面的输出结果

>>>parent()

Printingfromthe parent() function

Printingfromthe second_child() function

Printingfrom the first_child() function

注意内部函数定义的顺序无关紧要,和其它的函数一样,打印只会发生在内部函数运行的时候

而且,内部函数在父函数被调用之前不会生效,它们的局部作用域是父(),它们只作为局部变量存在在父()函数的内部,尝试调用first_child(),你会得到下面的错误

Traceback (most recent call last):

File"", line 1, in NameError: name'first_child' is not defined

不管你何时调用parent(),内部函数first_child()和second_child()都会被调用,因为它们的局部作用域,它们无法再parent()函数外使用

从函数中返回函数

python允许使用函数来作为返回值,下面的例子从外部的父函数parent()返回了一个内部函数

defparent(num):deffirst_child():return "Hi, I am Emma"

defsecond_child():return "Call me Liam"

if num == 1:returnfirst_childelse:return second_chil

注意这里返回的first_child是没有括号的,也就是返回了对函数first_child的引用, 带括号的first_child() 指的是对函数求值的结果,这个可以在下面的实例中看到

>>> first = parent(1)>>> second = parent(2)>>>first.first_child at 0x7f599f1e2e18>

>>>second.second_child at 0x7f599dad5268>

这个输出代表first变量引用了在parent()中的本地函数first_child(),second则指向了second_child()

你现在可以像常规函数一样使用first和second,虽然他们指向的函数无法被直接访问

>>>first()'Hi, I am Emma'

>>>second()'Call me Liam'

请注意,在前面的例子中我们在父函数中运行内部函数,例如first_child(),然后在最后的例子中,返回的时候没有给内部函数first_child添加括号。这样,就获取了将来可以调用的函数的引用。这样有意义吗?

简单装饰器

现在你已经看到函数和python中的其它对象一样,你已经准备好前进来认识python装饰器,让我们以一个例子开始:

defmy_decorator(func):defwrapper():print("Something is happening before the function is called.")

func()print("Something is happening after the function is called.")returnwrapperdefsay_whee():print("Whee!")

say_whee= my_decorator(say_whee)

你能猜到当你调用say_whee()的时候回发生什么么?试一下:

>>>say_whee()

Somethingis happening before the function iscalled.

Whee!

Somethingis happening after the function is called.

要理解这里发生了什么,需要回看下之前的例子,我们只是应用了你到目前为止学到的所有东西

所谓的装饰器发生在下面这行:

say_whee = my_decorator(say_whee)

事实上,say_whee现在指向了内部函数wrapper(),当你调用my_decorator(say_whee)的时候会将wrapper作为函数返回

>>>say_whee.wrapper at 0x7f3c5dfd42f0>

wrapper()引用原始的say_whee()作为func,在两个print()之间调用这个函数

简而言之:装饰器包裹一个函数,并改变它的行为

在继续之前,让我们看下第二个例子。因为wrapper()是一个常规的函数,装饰器可以以一种动态的方式来修改函数。为了不打扰你的邻居,下面的示例演示只会在白天运行的装饰器

from datetime importdatetimedefnot_during_the_night(func):defwrapper():if 7 <= datetime.now().hour < 22:

func()else:pass #Hush, the neighbors are asleep

returnwrapperdefsay_whee():print("Whee!")

say_whee= not_during_the_night(say_whee)

如果你在睡觉的时间调用say_whee(),不会发生任何事情

>>>say_whee()>>>

语法糖

上面的装饰器say_whee()用起来有一点笨拙。首先,你键入了三次say_whee,另外,装饰器隐藏在了函数的定义之下

作为替代,python允许你使用@symbol的方式使用装饰器,有时被称为"pie"语法,下面的例子和之前第一个装饰器做了同样的事情

defmy_decorator(func):defwrapper():print("Something is happening before the function is called.")

func()print("Something is happening after the function is called.")returnwrapper

@my_decoratordefsay_whee():print("Whee!")

所以,@my_decorator 只是say_whee = my_decorator(say_whee)的一种快捷方式,这就是如何将装饰器应用到函数上

复用装饰器

回想一下,装饰器只是一个普通的函数。所有常用的工具都是方便重复利用的,让我们将装饰器移动到他自己的模型上以便于在其它的函数上使用

下面创建了一个decorators.py

defdo_twice(func):defwrapper_do_twice():

func()

func()return wrapper_do_twice

注意:你可以随意定义内部函数的名称,通常像wrapper()用起来是没问题的。你在这篇文章中会遇到许多装饰器。为了区别开它们,我们将使用decorator名称来命名内部函数,但会加上wrapper_前缀。

你可以使用常规导入来使用一个新的装饰器

from decorators importdo_twice

@do_twicedefsay_whee():print("Whee!")

当你运行这个例子,你会看到原始韩式say_whee()执行两次

>>>say_whee()

Whee!

Whee!

装饰器传参

如果你有一个函数需要接收一些参数,这时候还可以再使用装饰器么,然我们试试

from decorators importdo_twice

@do_twicedefgreet(name):print(f"Hello {name}")

不幸的是,运行代码抛出了错误

>>> greet("World")

Traceback (most recent call last):

File"", line 1, in TypeError: wrapper_do_twice() takes 0 positional arguments but1 was given

问题在于内部函数wrapper_do_twice()没有接收任何参数,但是name="World"却传给了它。你可以让wrapper_do_twice()接收一个参数来修补这个问题,但是这样前面的say_whee()函数就无法工作了

解决方案是在内部函数使用*args和**kwargs ,这样它会允许接收任意个关键参数,下面重写了decorators.py

defdo_twice(func):def wrapper_do_twice(*args, **kwargs):

func(*args, **kwargs)

func(*args, **kwargs)return wrapper_do_twice

内部函数wrapper_do_twice()现在接收任意数量的参数并会传递给装饰的函数,目前say_whee()和greet()都会正常工作

>>>say_whee()

Whee!

Whee!>>> greet("World")

Hello World

Hello World

从装饰器返回值

被装饰的函数返回值会发生什么?这会由装饰器来决定,我们下面有一个简单的装饰器函数

from decorators importdo_twice

@do_twicedefreturn_greeting(name):print("Creating greeting")return f"Hi {name}"

尝试运行它:

>>> hi_adam = return_greeting("Adam")

Creating greeting

Creating greeting>>> print(hi_adam)

None

装饰器吃掉了从函数返回的值

因为do_twice_wrapper()没有返回值,调用 return_greeting("Adam") 最后返回了None

修复的方式是,需要确认装饰器返回它装饰的函数的值,改变decorators.py文件:

defdo_twice(func):def wrapper_do_twice(*args, **kwargs):

func(*args, **kwargs)return func(*args, **kwargs)return wrapper_do_twice

执行这个函数返回的值:

>>> return_greeting("Adam")

Creating greeting

Creating greeting'Hi Adam'

你是谁?

在使用Python(尤其是在交互式shell中)时,强大的内省是非常方便的功能。内省是对象在运行时了解其自身属性的能力。例如,函数知道自己的名称和文档:

>>> print

>>> print.__name__

'print'

>>> help(print)

Help on built-in function print inmodule builtins:print(...)

内省同样适用于你自定义的函数:

>>>say_whee.wrapper_do_twice at 0x7f43700e52f0>

>>> say_whee.__name__

'wrapper_do_twice'

>>>help(say_whee)

Help on function wrapper_do_twiceinmodule decorators:

wrapper_do_twice()

然而在被装饰后,say_whee()会对自身感到疑惑。它现在显示为 do_twice()装饰器的内部函数 wrapper_do_twice()

为了修复这个,装饰器需要使用@functools.wraps装饰器,它会保留原始函数的信息,再次更新下decorators.py:

importfunctoolsdefdo_twice(func):

@functools.wraps(func)def wrapper_do_twice(*args, **kwargs):

func(*args, **kwargs)return func(*args, **kwargs)return wrapper_do_twice

不需要对被装饰的say_whee()函数做任何更改:

>>>say_whee

>>> say_whee.__name__

'say_whee'

>>>help(say_whee)

Help on function say_wheeinmodule whee:

say_whee()

非常好,现在say_whee()在被装饰后可以保持自己

技术细节:@funtools.wraps 装饰器使用函数functools.update_wrapper()来更新指定的属性,像__name__和__doc__来用于自省

一些现实中的例子

让我们看一些用处更大的装饰器例子。你会注意到他们主要的模式和你现在所学的都是一样的

importfunctoolsdefdecorator(func):

@functools.wraps(func)def wrapper_decorator(*args, **kwargs):#Do something before

value = func(*args, **kwargs)#Do something after

returnvaluereturn wrapper_decorator

对于构建更复杂的装饰器,这个是一个很好的模板

时间函数

让我们从@timer装饰器开始,它会测量函数运行的时间并且打印持续时间到控制台,这是代码:

importfunctoolsimporttimedeftimer(func):"""Print the runtime of the decorated function"""@functools.wraps(func)def wrapper_timer(*args, **kwargs):

start_time= time.perf_counter() #1

value = func(*args, **kwargs)

end_time= time.perf_counter() #2

run_time = end_time - start_time #3

print(f"Finished {func.__name__!r} in {run_time:.4f} secs")returnvaluereturnwrapper_timer

@timerdefwaste_some_time(num_times):for _ inrange(num_times):

sum([i**2 for i in range(10000)])

这个函数是在函数运行之前获取时间(#1行),并且在函数运行结束之后获取时间(#2行),我们使用 time.perf_counter() 函数,这个函数可以非常好的计算时间间隔。下面是一个示例:

>>> waste_some_time(1)

Finished'waste_some_time' in 0.0010secs>>> waste_some_time(999)

Finished'waste_some_time' in 0.3260 secs

自己运行测试下,手敲下这里的代码,确保你理解它的工作原理。如果不明白,也不要担心。装饰器是高级方法,试着思考下或者画下流程图

注意: 如果你只是想获取函数的运行时间,@timer 装饰器可以满足。如果你想获取到更精确的数据,你应该考虑使用timeit 模块来替代它。它临时禁用了垃圾收集并且运行多次以避免函数快速调用带来的噪音数据

调试代码

下面的@debug函数会在每次调用的时候打印函数被调用的参数和它的返回结果

importfunctoolsdefdebug(func):"""Print the function signature and return value"""@functools.wraps(func)def wrapper_debug(*args, **kwargs):

args_repr= [repr(a) for a in args] #1

kwargs_repr = [f"{k}={v!r}" for k, v in kwargs.items()] #2

signature = ",".join(args_repr + kwargs_repr) #3

print(f"Calling {func.__name__}({signature})")

value= func(*args, **kwargs)print(f"{func.__name__!r} returned {value!r}") #4

returnvaluereturn wrapper_debug

signature 变量是通过 字符串表示方法 来创建所有的输入参数。下面的数字对应了代码中的注释

1、将args创建为列表,使用repr修饰

2、将kwargs创建为列表,使用f-string格式化参数为key=value,!r表示使用repr()表示值

3、args和kwargs转换后会合并在signature变量中,使用逗号分隔每个变量

4、函数运行结束后会返回值

让我们在一个简单的函数中使用装饰器被观察它是如何运行的,被装饰的函数只有一个位置参数和一个关键字参数

@debugdef make_greeting(name, age=None):if age isNone:return f"Howdy {name}!"

else:return f"Whoa {name}! {age} already, you are growing up!"

注意@debug装饰器如何打印make_greeting()函数的signature 和返回值

>>> make_greeting("Benjamin")

Calling make_greeting('Benjamin')'make_greeting' returned 'Howdy Benjamin!'

'Howdy Benjamin!'

>>> make_greeting("Richard", age=112)

Calling make_greeting('Richard', age=112)'make_greeting' returned 'Whoa Richard! 112 already, you are growing up!'

'Whoa Richard! 112 already, you are growing up!'

>>> make_greeting(name="Dorrisile", age=116)

Calling make_greeting(name='Dorrisile', age=116)'make_greeting' returned 'Whoa Dorrisile! 116 already, you are growing up!'

'Whoa Dorrisile! 116 already, you are growing up!'

@debug修饰符看起来只是重复了我们刚才写的内容 ,并不是非常有用。 但当应用到不能直接修改的其它函数时,它会更加强大。

下面的例子计算了一个数学常数E的近似值

importmathfrom decorators importdebug#Apply a decorator to a standard library function

math.factorial =debug(math.factorial)def approximate_e(terms=18):return sum(1 / math.factorial(n) for n in range(terms))

这个例子还演示了如何将装饰器应用到已经定义了的函数

当调用approximate_e()函数,你可以看到@debug函数在工作:

>>> approximate_e(5)

Calling factorial(0)'factorial' returned 1Calling factorial(1)'factorial' returned 1Calling factorial(2)'factorial' returned 2Calling factorial(3)'factorial' returned 6Calling factorial(4)'factorial' returned 24

2.708333333333333

在这个例子中,可以得到一个真实值的近似值e = 2.718281828

给代码降速

下面的例子看起来可能不是很有用。可能最常见的用例是,您希望对一个不断检查资源是否存在的函数进行速率限制 。 @slow_down decorator在调用被修饰的函数之前会暂停一秒钟

importfunctoolsimporttimedefslow_down(func):"""Sleep 1 second before calling the function"""@functools.wraps(func)def wrapper_slow_down(*args, **kwargs):

time.sleep(1)return func(*args, **kwargs)returnwrapper_slow_down

@slow_downdefcountdown(from_number):if from_number < 1:print("Liftoff!")else:print(from_number)

countdown(from_number- 1)

来看下@slow_down装饰器的效果,你需要自己运行跑下

>>> countdown(3)3

2

1Liftoff!

countdown()是一个递归函数。也就是说,它是一个调用自身的函数 。

注册插件

装饰器不是必须要修饰被装饰的函数(这句话不太好翻译,看下面的例子理解起来很容易),它还可以简单地注册一个函数,并将其解包返回,例如,可以使用它来创建一个轻量级插件体系结构:

importrandom

PLUGINS=dict()defregister(func):"""Register a function as a plug-in"""PLUGINS[func.__name__] =funcreturnfunc

@registerdefsay_hello(name):return f"Hello {name}"@registerdefbe_awesome(name):return f"Yo {name}, together we are the awesomest!"

defrandomly_greet(name):

greeter, greeter_func=random.choice(list(PLUGINS.items()))print(f"Using {greeter!r}")return greeter_func(name)

@register装饰器只是在全局PLUGINS 字典中储存了被装饰函数的引用。注意你不需要在例子中写内部函数或者使用@functools.wraps ,因为返回的是一个未经过修改的初始函数

randomly_greet()函数在注册函数中随机选择一个使用。注意PLUGINS字典已经包含了对注册为插件的每个函数对象的引用:

>>>PLUGINS

{'say_hello': ,'be_awesome': }>>> randomly_greet("Alice")

Using'say_hello'

'Hello Alice'

这个插件的主要用处在于不需要再单独维护一个插件列表。这个列表在插件注册时自动创建,使得添加一个新插件变得很简单,只需定义函数并用@register装饰即可。

如果你对python中的globals()函数熟悉,你可能会看到一些和我们的插件结构相似之处。globals()可以访问当前作用于的所有全局变量

包括我们的插件:

>>>globals()

{...,#Lots of variables not shown here.

'say_hello': ,'be_awesome': ,'randomly_greet': }

使用@register 装饰器,可以创建感兴趣的变量管理列表,有效地从globals()中筛选出一些函数

用户是否登录?

在继续讨论一些更有趣的装饰器之前,让我们在最后一个示例中演示通常在处理web框架时使用的装饰器。在这个例子中,我们使用Flask去设置一个/secret web页面,这个页面只对登录用户或者其他有权限的用户展示

from flask importFlask, g, request, redirect, url_forimportfunctools

app= Flask(__name__)deflogin_required(func):"""Make sure user is logged in before proceeding"""@functools.wraps(func)def wrapper_login_required(*args, **kwargs):if g.user isNone:return redirect(url_for("login", next=request.url))return func(*args, **kwargs)returnwrapper_login_required

@app.route("/secret")

@login_requireddefsecret():

...

虽然这里演示了如何对web框架添加身份验证吗,但通常不应该自己编写这些类型的装饰器。对于Flask可以使用Flask-login扩展,这里的功能更丰富也更加安全

有想象力的装饰器

到目前为止,你已经看到了如何创建简单的装饰器并且非常了解什么是装饰器以及它们是如何工作的。请从这篇文章中休息一下,练习学到的一切。

在本教程的第二部分中,我们将探索更高级的特性,包括如何使用以下特性:

1、在类上使用装饰器(装饰类)

2、在一个函数上应用多个装饰器

3、带参数的装饰器

4、可以选择是否接收参数的装饰器

5、带状态的装饰器

6、类装饰器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/537235.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我的2018

写在开始 2018年以飞快的速度临近尾声了&#xff0c;只感慨时间过得真快&#xff01; 这一年过得算是平平淡淡&#xff0c;没有比较特别的地方。 工作 从去年8月来到这公司&#xff0c;是个做旅游产品的互联网公司&#xff0c;平时里做的事可以说是很简单&#xff0c;我只能说&…

IntelliJ IDEA快捷键总结

搜索类快捷键 快捷键描述Ctrl F文件内查找字符串Ctrl Shift F按照文本的内容查找双击Shift查找任何内容&#xff0c;可搜索类、资源、配置项、方法等&#xff0c;还能搜索路径Ctrl Shift R全局资源查找和替换Ctrl N按类名搜索类&#xff0c;比如 Java&#xff0c;Groovy…

python小波分析法检测火焰_一种基于小波分析的网络流量异常检测方法

一种基于小波分析的网络流量异常检测方法杜臻;马立鹏;孙国梓【期刊名称】《计算机科学》【年(卷),期】2019(046)008【摘要】对大量网络流量数据进行高质量特征提取与异常识别是做好网络取证的重要基础.文中重点研究并实现了网络取证中的数据处理并建立了模型库.对一种基于小波分…

初学Linux第三周

简单shell脚本&#xff1a;#!/bin/bash 第一行必须包括shell声明序列&#xff1a;#!##********************************************************************#Author: *****#QQ: *****#Date: 2018-12-31#FileName&#xff1a; hello.sh#URL: http#Descriptio…

python使用ddt找不到方法_python使用ddt过程中遇到的问题及解决方案【推荐】

前言&#xff1a;在使用DDT数据驱动HTMLTestRunner输出测试报告时遇到过2个问题&#xff1a;1、生成的测试报告中&#xff0c;用例名称后有dict() -> new empty dictionary2、使用ddt生成的用例名称无法更改1、用例名称后有dict() -> new empty dictionary报告中用例名称…

合同的不含税与税额怎么算

假设税率是6% 不含税金额&#xff1d;总金额/1.06 税额&#xff1d;不含税金额0.06 增值税在线计算器&#xff1a;http://www.ab126.com/goju/7332.html 大小写转换&#xff1a;https://link.fobshanghai.com/rmb.htm?t1525225925284 工作日计算&#xff1a;http://www.fy…

Promise进阶——如何实现一个Promise库

概述 从上次更新Promise/A规范后&#xff0c;已经很久没有更新博客了。之前由于业务需要&#xff0c;完成了一个TypeScript语言的Promise库。这次我们来和大家一步一步介绍下&#xff0c;我们如何实现一个符合Promise/A规范的Promise库。 如果对Promise/A规范还不太了解的同学&…

python中isinstance(3、object)_python中isinstance函数判断各种类型的小细节

1. 基本语法isinstance(object, classinfo)Return true if the object argument is an instance of the classinfo argument, or of a (direct, indirect or virtual)subclass thereof. Also return true if classinfo is a type object (new-style class) and object is an ob…

[前端漫谈] 做一个四则计算器

0x000 概述 近期重新开始学习计算机基础方面的东西&#xff0c;比如计算机组成原理、网络原理、编译原理之类的东西&#xff0c;目前正好在学习编译原理&#xff0c;开始对这一块的东西感兴趣&#xff0c;但是理论的学习有点枯燥无味&#xff0c;决定换种方式&#xff0c;那就是…

程序员笔试面试后上机_hcie面试有哪些要注意的事项?

大家都知道&#xff0c;华为认证hcie考试分为三个部分&#xff0c;分别是笔试、lab实验和面试。其中&#xff0c;考生讨论得最多的就是面试部分&#xff0c;因为面试不同于笔试和lab实验&#xff0c;自己埋头答题和操作就行&#xff0c;面试要面对考官&#xff0c;考核的东西非…

【Infragistics教程】在javascript构造函数中创建基本继承

2019独角兽企业重金招聘Python工程师标准>>> 【下载Infragistics Ultimate最新版本】 用javascript创建对象有四种方法。具体如下&#xff1a; 对象作为文本构造函数调用模式创建&#xff08;&#xff09;方法在ES6之后使用类继承的实现因对象创建方法而异。本文将解…

python爬虫ssl错误_Python爬虫:Requests的SSLError:certificate verify failed问题解决方案6条...

问题&#xff1a;脚本是用Python写的&#xff0c;用到开源库play-scraper&#xff0c;调用其collectionAPI来获取Google Play的Top App列表。该库使用了requests作为客户端来对Google Play进行操作。当脚本执行时&#xff0c;会报如下错误&#xff1a;certificate verify faile…

2019年1月3日

数组 字面量创建数组 1. var arr[]; []里边可以放数字&#xff0c;字符串&#xff0c;true&#xff0c;false&#xff0c;null&#xff0c;undefined&#xff0c;数组&#xff08;[1,2,3]&#xff09;&#xff0c;对象{x&#xff1a;1&#xff0c;y&#xff1a;2} var arr[1,2…

vertex 3.0 与SpringBoot混合开发之初探

SpringBoot是最近几年比较流行的web应用开发框架&#xff0c;它是微服务的一个开发框架。它的Web服务器内核为Tomcat或Jetty&#xff0c;它们作为Servlet容量来对客户端的http/https请求进行解析。最近&#xff0c;spring.io又出推出一套新的服务器内核框架&#xff0c;它就是W…

switch芯片和phy芯片的区别_感应式芯片卡CPU卡的FM1208-9和FM1208-10有什么区别,你知道吗?...

感应式CPU卡是目前芯片卡中安全系统较高的芯片&#xff0c;使用范围也较为广泛&#xff0c;但是这款CPU分为FM1208-9和FM1208-10&#xff0c;那你们知道分别代表什么意思呢&#xff1f;他们之间有什么不同呢&#xff1f;CPU白卡FM是什么&#xff1f;首先&#xff0c;我们来说下…

每次登陆都要滑动验证_湖人队冠军成员卡鲁索很吃香:每次谈判都有N支球队点名要他...

10月24日NBA直播台讯&#xff1a;洛杉矶湖人队助理教练迈克-彭伯西在接受媒体采访时透露&#xff0c;湖人队替补控球后卫卡鲁索目前在联盟中很吃香。湖人队每次进行交易谈判时&#xff0c;对方球队都点名想要卡鲁索。彭伯西表示&#xff1a;“每一次我们在休赛期或者交易截止日…

[HAOI2015]按位或

朴素的 f[S]表示S到(1<<n)的期望次数 发现1的个数只增加不减少 所以可以类似拓扑序的图&#xff0c;然后枚举子集O(3^n)转移 没有优化的余地 另辟蹊径&#xff1a; 拆开每一位来看 t[i]表示第i位变成1的次数 ansE(max(t[i])) 根据min-max容斥 得到&#xff1a;ans∑E(t[i…

MySQL在DOS指令里面的使用以及增删改查的使用

本人的第一条博客&#xff0c;选中我的电脑单机右键&#xff0c;点开管理&#xff0c;选中服务找到MySQL57.启动该服务。回退至桌面&#xff0c;按住winR 输入cmd打开DOS指令的窗口。 在窗口输入: mysql -h localhost -u root -p 显示password输入提示&#xff1a;表示已经…

node+socket.io 实现一个聊天室

我们只做简单的实现&#xff0c;不接入数据库&#xff0c;nodejs也不使用express和koa等框架 因此依赖只有两个&#xff1a; 1、socket.io 2、mime&#xff08;用于获取静态资源时获取文件的mime类型&#xff09; 安装命令&#xff1a; npm install socket.io mime --save 其他…

安卓应用用户数据_用户指标数据应用

一、如何理解数据用户数据&#xff1a;gender:性别、 birthday:出生日期行为数据&#xff1a;user_id:用户id、auction_id:购买行为编号、buy_mount:购买数量、day:购买时间商品数据&#xff1a;cat_id:商品种类ID、cat1:商品类别、property:商品属性二、用户数据指标1.用户数据…