一、函数、名称空间与作用域

  1.函数的构成

    python有三种层次的抽象:(1)程序可分成多个模块;(2)每个模块包含多条语句;(3)每条语句对对象进行操作。函数大致处于第二层。函数有它的定义格式、参数、逻辑代码块、返回值、以及函数属性五部分组成。

 def foo(name):  # foo: 别名; (),执行规则; name, 形式参数
"""doc""" # 说明文档,可以用foo.__doc__获取
return name # 返回值
print(foo("foo")) # 填写形式参数对应的实体参数,并执行foo函数
f = foo     # 函数别名可以赋值
print(f("foo"))

  2.函数与方法

    函数和方法是有一些区别的,提到方法一般指的是某个对象的方法。因为python自上而下执行,所以函数不可以提前声明。但是方法可以,例如类对象中,可以直接调用后面的方法。但当方法或者函数被调用时,都是函数。

 class Foo:
def pri(self):
return foo()
def foo(self, name):
return name
f = Foo()
f.pri("foo")

  3.名称空间与作用域

    - 名称空间

      名称空间是站在程序的角度对抽象的结构进行划分。

      python使用名称空间(namespaces)的概念在应用程序上储存关于对象的信息和位置。内置函数、语句和对象有特殊的命名空间,函数、模块有单独的命名空间,也就是两者有各自的命名空间,及特定的抽象级别。在特定的抽象级别上访问对象或函数时,都将搜寻名称空间表以获得可引用的特定名字,并确定处理存储在该位置的信息的方法。

      函数的参数,加上函数体中绑定的所有变量(通过赋值或者其它绑定语句,如def),功能构成了该函数的本地命名空间(local namespace),也称为本地范围(local space)。所有这些也称为该函数的本地变量(local variable)。

      其它则是全局名称空间,包括可被其它函数或模块直接调用的、存活于整个程序运行期间的变量、函数、模块等。

    - 作用域

      作用域是站在对象的角度查看它的适用范围。在python中,作用域遵循以下规则:

        - 每个模块都有自己的作用域,这意味着多重模块有它们自己的作用域,从而形成自己的名名称空间。

        - 定义新函数时创建新的作用域,作用域仅限于函数体内。

        - 每个未缩进的逻辑代码块,它的作用域是全局的。

  4.全局变量和局部变量

    定义在最高级别的模块中的变量,被称为全局变量;定义在局部作用域中的变量被称为局部变量。一个变量的作用域和它寄宿的名称空间相关。

    python变量遵循LGB规则:

      - 变量引用依次搜寻3种作用域:局部(Local)、全局(Global)、内置(Built-in)。

      - 在局部作用域内对变量赋值时会创建新对象或更新对象,如果想在局部作用域对全局对象赋值,必须使用关键字global。

      - 全局声明会把赋值名字映射到封装的模块的作用域。这意味着,要么显示地从输入的模块中输入对象,要么使用完全有效的模块/对象名。

    示例一:GLB规则

 a = 20
def func():
print(a) # 在局部作用域找不到a,会继续从全局作用域找a
func()
# 打印ax  

    示例二:全局变量与局部变量的互不干扰

 a = 20  # 全局变量
def func():
b = 25
a = 30
global c
c = 125
print(a)
print(b)
print(a)
func()
print(c)
print(a)
# 打印结果为:
20
30
25
125
20

    也就是说,创建局部变量a,是直接开辟内存生成对象30,然后引用给a。它与全局变量的a毫不相关。global可以修改局部变量为全局变量。

    globals()函数和locals()函数可以直接查看当前文件中的全局变量和局部变量。

  5、参数

    python函数中的传递参数,是传递变量的值本身,而不是创建一个新的引用。

    在定义函数时,有位置参数,默认参数,以及扩展参数;在调用函数时,可以按位置传递相应的变量,也可以按键值对传递相应的参数,也可以以扩展的方式传递参数。

    在定义函数时,位置参数、默认参数与扩展参数的顺序是:位置参数 > 扩展元组 > 默认参数 > 扩展字典。

 def func(a, b, *args, author="jingyu", **kwargs):
print(a)
print(b)
print(args)
print(author)
print(kwargs)
 func(123, 456, 7,8,9, gender="female", age=20)
# 打印结果为:
123
456
(7, 8, 9)
jingyu
{'gender': 'female', 'age': 20}

    在定义函数时,*args会把所有位置参数匹配剩余的变量组合成元组,**kwargs会把关键字参数(键值对)组合成一个字典。

    在执行函数时,*list或者*tuple会把所有的元素展开成单独的位置参数,**dict会把字典内的键值对展开成关键字参数。

    这个功能在写闭包和装饰器的时候非常有用。

 func(
123, 456,
*[7, 8, 9], *[10, 11, 12], *{"name1": "sunbin", "name2": "mengtian"},
**{"name3": "baiqi", "gender": "female", "age": 72},
)
# 打印结果为:
123
456
(7, 8, 9, 10, 11, 12, 'name1', 'name2')
jingyu
{'name3': 'baiqi', 'gender': 'female', 'age': 72}

  6、函数属性

    可以给函数创建一些属性,并通过func.__dict__来查看。函数属性应用在高度专业的应用程序中。

 def say():
print("hello, my man.")
# 接上面定义的func
func.__live__ = 20
func.__create__ = "2018_04_18"
func.say = say
print(func.__dict__)
# 打印结果为:
{'__create__': '2018_04_18', '__live__': 20, 'say': <function __main__.say>}
# 显然它可以执行
func.say()
# 结果显示
hello, my man.
# 这个和js的匿名函数有些类似,但是不支持func.say = function (){console.log("hello, my man.)} 这种写法

二、闭包

  闭包是内层函数对层函数局部变量的引用。简单来说,闭包就是内部包含函数的函数。

  闭包的好处:如果python检测到闭包,它有一个机制,局部作用域不会随着函数的结束而结束。可以在局部作用域添加缓存机制,使得对于计算量较大时能够提高效率。闭包也是装饰器的前提。

  1、创建闭包

 def outer(name):
def inner(age):
return "hello, i'm %s, %s." % (name, age)
return inner
outer("baiqi")(72)
# 打印结果为:
"hello, i'm baiqi, 72."

  可以看到,outer("baiqi")的返回值是一个函数对象,即inner,inner可以接收参数并执行,它的返回值是真正要打印的结果。可以隐隐地感觉到,outer这个外层函数实际是在打印真正结果之前做了一些额外的"修饰"工作。

  2、闭包中的外层变量和内层变量也遵循GLB规则

  def outer():
a = 100
def inner1():
return a * 5
b = inner1()
def inner2():
return b * 10
a = inner2()
def inner3():
b = a
print(a, b)
inner3()
print(a, b)
outer()
# 打印结果为:
5000 5000
5000 500

    闭包里可以写很多逻辑代码和函数,闭包并不一定要返回某个具体的内层函数,闭包有着很好的灵活性和弹性,它相当于一个工作室。

三、装饰器

  1、装饰器函数的推导

    重写一下白起打招呼:

 import time
def hello():
print("Hello, i'm baiqi, 72 years old.") def timer():
t = time.strftime("%Y-%m-%d %X", time.localtime())
print(t)
return hello()

    把它改写成闭包的形式:

 def timer():
t = time.strftime("%Y-%m-%d %X", time.localtime())
print(t)
def fn():
return hello()
return fn
timer()()

    前面说到outer("baiqi")返回的是一个待执行的函数,这里也是,timer()返回的是fn,fn()执行时返回hell()执行的结果。于是正常显示:

 2018-04-18 23:03:54
Hello, i'm baiqi, 72 years old.

    hello这个返回值不够灵活,把hello函数作为对象传进来;并且timer()运行时直接打印了t,它是timer()函数的运行时间而不是hello的,于是改写为:

 def timer(f):
def fn():
t = time.strftime("%Y-%m-%d %X", time.localtime())
print(t)
return f()
return fn
timer(hello)()

    此时如果要只写hello()函数就打招呼,而不是用timer(hello)()这个额外的函数名,可以改写为:

 import time
def hello():
print("Hello, i'm baiqi, 72 years old.")
def timer(f):
def fn():
t = time.strftime("%Y-%m-%d %X", time.localtime())
print(t)
return f()
return fn
hello = timer(hello)
print(hello, hello.__name__)
hello()
# 打印结果为:
<function timer.<locals>.fn at 0x10f201d08> fn
2018-04-18 23:12:57
Hello, i'm baiqi, 72 years old.

    在hello = timer(hello)这一步,把原来的hello函数作为参数传递给timer,那么timer(hello)的返回值就是未执行的fn函数。fn函数在执行时,也就是timer(hello)() = fn() = hello(),会返回print字符串。

    在python中,用@符号来代表hello = timer(hello)这个关系式,并要求def hello()写在它的下面。即:

 import time
def timer(f):
def fn():
t = time.strftime("%Y-%m-%d %X", time.localtime())
print(t)
return f()
return fn
@timer
def hello():
print("Hello, i'm baiqi, 72 years old.")
hello()

    注意:逻辑代码写内层函数里面。上面将t写在外面时,有运行timer()会直接打印调用时间,这个需要避免。可以在fn函数的内部尽情地写if for while 等等代码块,也不一定非要返回f()。

    可以看出装饰器的作用:在尽量保留被装饰函数的基础上,不着痕迹地添加一些额外的功能。“尽量保留”说明它的确修改了原函数的一些内容,如函数名称(fn而不是hello),

 print(hello.__name__)
# 打印结果为:
fn

    “不着痕迹”是指不要在外层函数的局部作用域内写逻辑代码,除非业务需要。

  2、装饰器函数传递参数

 import time
def timer(f):
def fn(name, age):
t = time.strftime("%Y-%m-%d %X", time.localtime())
print(t)
return f(name, age)
return fn
@timer
def hello(name, age):
print("Hello, i'm %s, %d years old." % (name, age))
hello("wangjian", 62)

    因为fn返回和执行hello本身,所以在hello中传递参数,就需要在fn中传递参数。为了使fn和返回执行的f函数(就是hello)具有更大的灵活性,通常会这么写:

 import time
def timer(f):
def fn(*args, **kwargs):
t = time.strftime("%Y-%m-%d %X", time.localtime())
print(t)
return f(*args, **kwargs)
return fn
@timer
def hello(name, age):
print("Hello, i'm %s, %d years old." % (name, age))
hello("limu", 62)

    前面已提到*args和**kwargs在定义函数和执行函数的功能。这里再重申一遍:在定义函数时,*args会将位置参数上传递的元素组合成元组,该元组赋给了变量args;在执行函数时,*args(此时args是一个元组(limu, 62))会把元组展开成元素。于是name还是那个name,age还是那个age。

 class Cla(object):
def __init__(self, *args, **kwargs):
# l1 = *args # SyntaxError can't use starred expression here
print(*args)
# l1 = args # l1 = (1, 2, 3)
# l1, l2, l3 = args # l1 = 1
print(*kwargs)
def __call__(self):
print("hello, world!") def func(*args, **kwargs):
return Cla(*args, **kwargs) func(1,2,3, name=123, age=123)()

    这也说明,fn的参数和f的参数必须保持一致。

  3、装饰器上带参数

 import time
def hello(name, age):
print("Hello, i'm %s, %d years old." % (name, age))
def gender(male=False):
def timer(f):
def fn(*args, **kwargs):
t = time.strftime("%Y-%m-%d %X", time.localtime())
print(t)
f(*args, **kwargs)
if male:
print(" I'm hero.")
else:
print("I'm beautiful girl.")
return fn
return timer
f1 = gender(male=True) # f1就是gender函数执行的返回值,也就是timer
f2 = f1(hello) # f2就是timer(f)函数执行的返回值,也就是fn
f2("limu", 62)

    改写一下丑陋的f1和f2:

 gender = gender(male=True)  # f1就是gender函数执行的返回值,也就是timer
hello = gender(hello) # f2就是timer(f)函数执行的返回值,也就是fn
hello("limu", 62)

    再把gender和hello写到一行:

 hello = gender(male=True)(hello)

    它符合装饰器的写法,即如果有hello=timer(hello),那么有@timer。于是这里可写为@gender(male=True)。最后,杨玉环打招呼了。

 import time
def gender(male=False):
def timer(f):
def fn(*args, **kwargs):
t = time.strftime("%Y-%m-%d %X", time.localtime())
print(t)
f(*args, **kwargs)
if male:
print(" I'm hero.")
else:
print("I'm beautiful girl.")
return fn
return timer
@gender(male=False)
def hello(name, age):
print("Hello, i'm %s, %d years old." % (name, age))
hello("yangyuhuan", 62)

    打印结果为:

 2018-04-19 00:07:25
Hello, i'm yangyuhuan, 62 years old.
I'm beautiful girl.

  4、装饰器的叠加:

    此时,又有一个要求,要打印这个人物的国家。可以在gender里再添加一个参数,在fn函数里去写细节的逻辑代码。现在用另一种方式实现要求:

 import time
def timer(f):
def fn(*args, **kwargs):
t = time.strftime("%Y-%m-%d %X", time.localtime())
print(t)
f(*args, **kwargs)
return args
return fn
def country(f):
def fn(*args, **kwargs):
variables = f(*args, **kwargs)
if args[0] == "yangyuhuan":
print("A beautiful girl, from TangChao.")
else:
print("A hero from ZhanGuo.")
return fn
@country
@timer
def hello(name, age):
print("Hello, i'm %s, %d years old." % (name, age))
hello("yangyuhuan", 24)

    打印结果为:

 2018-04-19 00:17:59
Hello, i'm yangyuhuan, 24 years old.
A beautiful girl, from TangChao

    注意:两个装饰器叠加,第一个装饰器最好写返回值。叠加的装饰器由上而下装饰,由下而上执行。

  5、漏掉的functools

    前面提到hello.__name__是fn,即内层的那个函数名。这在框架里面是不允许出现的,于是有了个functools.wraps()方法能完整保留被装饰函数的完整信息。它的用法也十分简单。

 import time, functools
def timer(f):
@functools.wraps(f)
def fn():
t = time.strftime("%Y-%m-%d %X", time.localtime())
print(t)
return f()
return fn
@timer
def hello():
print("Hello, i'm baiqi, 72 years old.")
print(hello.__name__)
# 打印结果为
hello

  6、类装饰器

    类装饰器写法一:

 import functools, time
class Add(object):
def __call__(self, f):
@functools.wraps(f)
def decorator(*args, **kwargs):
t1 = time.time()
outcome = f(*args , **kwargs)
time.sleep(1)
t2 = time.time()
print("t: %r " % (t2 - t1))
return decorator @Add()
def add(var1, var2):
return var1 * var2
add(4, 5)

    类装饰器写法二:

 class Add(object):
def add(self,f):
@functools.wraps(f)
def fn(var1, var2):
t1 = time.time()
outcome = f(var1 , var2)
t2 = time.time()
print("t: %r " % (t2 - t1))
return outcome
return fn
myAdd = Add()
@myAdd.add
def add(var1, var2):
return var1 * var2
add(4, 5)

    类装饰器写法三:

 class Add(object):
def __init__(self, appname):
self.appname = appname
self.function_dict = {}
def add(self,route):
def decorator(f):
@functools.wraps(f)
def fn(*args, **kwargs):
t1 = time.time()
outcome = f(*args, **kwargs)
t2 = time.time()
print("t: %r " % (t2 - t1))
self.function_dict[route] = fn.__name__
return outcome
return fn
return decorator app = Add("apple") @app.add("/index")
def add(var1, var2):
return var1 * var2
print(add(4, 5))
print(app.function_dict)

    打印结果为:

 t: 1.9073486328125e-06
20
{'/index': 'add'}

四、列表生成式、匿名函数和高阶函数

  1、列表生成式[列表推导式]

    列表生成式是可迭代对象迭代时的一种简便写法。

 table = [
{"name": "baiqi", "attr": "guy", "rank": 1},
{"name": "limu", "attr": "guy", "rank": 2},
{"name": "wangjian", "attr": "guy", "rank": 3},
{"name": "lianpo", "attr": "guy", "rank": 4},
{"name": "xishi", "attr": "girl", "rank": 1},
{"name": "wangzhaojun", "attr": "girl", "rank": 2},
{"name": "diaochan", "attr": "girl", "rank": 3},
{"name": "yangyuhuan", "attr": "girl", "rank": 3},
] name = [person["name"] for person in table] name = [[person["name"], person["attr"], person["rank"]] for _, person in enumerate(table)]
name = [{person["name"]: person["rank"]} for _, person in enumerate(table)] name = {person["name"]: [person["attr"], person["rank"]] for _, person in enumerate(table)} boy = [person["name"] for person in table if person["attr"] == "guy"]
boy = [person["name"] for person in table if person["rank"] >= 3] girl = [person["name"] if person["rank"] >3 and person["attr"] == "girl" else -1 for person in table]

  实际上,列表生成式的使用要比上面的例子中更灵活。比如两层循环或者两个可变序列情形时。

  2、匿名函数

    对于上面的第一个name,可以用lambda函数来重写。同样地,可以用lambda改写上面所有的列表生成式。lambda还支持传入函数,但是没有必要性,它的核心在于简洁。

    lambda params: expression。

 func = lambda lis: [person["name"] for person in lis]
func(table)

  3、三个高阶函数

    高阶指的是该函数的作用域和存在的名称空间,以及它替代一些逻辑代码块的作用。

    apply(FUNCTION, TUPLE)。快要被摒弃的函数。reduce(),逐步叠加计算,在python3中已不存在了。

    map(FUNCTION),遍历,function作用在序列的每个元素上以改变元素。filter(FUNCTION),过滤,function作用在序列的每个元素上,进行条件判断并返回符合条件的元素。这些函数都不改变原序列。

 number = list(range(1, 11, 2))
outcome1 = list(map(lambda x: x**2, number))
outcome2 = list(filter(lambda x: x>4, number))
print(outcome1)
print(outcome2)

    需要注意的是,map函数和filter函数的返回结果是map对象和filter对象,需要list转换一下。这些高阶函数apply函数和map函数也会以方法的形式出现在一些第三方模块中。

 import pandas as pd
df = pd.DataFrame(table)
df["name_map"] = df.name.map(lambda x: x + "_China")
print(df)
# 打印结果为: attr name rank name_map
0 guy baiqi 1 baiqi_China
1 guy limu 2 limu_China
2 guy wangjian 3 wangjian_China
3 guy lianpo 4 lianpo_China
4 girl xishi 1 xishi_China
5 girl wangzhaojun 2 wangzhaojun_China
6 girl diaochan 3 diaochan_China

  4、偏函数

    偏函数的功能和上下文管理器一致。都是管理上下文的开始和结束,即with ... 直到结束。在tensorflow及其它的一些框架中,reader()这个阅读器的功能随处可见,可见它功能还是很强大的。

 f1 = open("homework/user.txt", mode="r", encoding="utf-8")
data = f1.readlines()
f1.close() with open("homework/user.txt", mode="r", encoding="utf-8") as f3:
data = f3.readlines() import functools
reader = functools.partial(open, mode="r", encoding="utf-8")
f3 = reader("homework/user.txt")
f3.readlines()

  5.递归函数

    在函数的内部调用自己本身的函数称为递归函数,递归的最大深度为998。两个例子:

 # 利用递归函数求阶乘
def factorial(number, start=1):
fac = 1 if start in [0, 1] else start
if start < int(number):
return factorial(number, start+1) * fac
else:
return fac

    注意,函数内部的factorial(number, start+1)就相当于fac。这是它的返回结果,递归函数必须存在可以终止的return。另一个特性,递归函数会在当件未满足时一直递归。

 # 二分查找
def func(value, l, index=0):
"""返回被查找值的索引"""
middle = len(l) // 2 # 切片
if middle == 0: # 当middle为0时,说明len(l)的值<=1
return 0 if value == l[0] else None
if value > l[middle]:
index += middle
return func(value, l[middle:], index)
elif value < l[middle]:
return func(value, l[: middle], index)
else:
return l.index(value) + index l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88, 100]
print(func(2, l))
print(func(100, l))
print(func(14, l))
# 打印结果为
#
#
# None

  6.内置函数

    python3.6.4官方文档中给出的内置函数如下。

    

python(三):函数的更多相关文章

  1. 第三章:Python基础の函数和文件操作实战

    本課主題 Set 集合和操作实战 函数介紹和操作实战 参数的深入介绍和操作实战 format 函数操作实战 lambda 表达式介绍 文件操作函数介紹和操作实战 本周作业 Set 集合和操作实战 Se ...

  2. 对Python中函数参数类型及排序问题,三个方面的总结

    Python中函数的参数问题有点复杂,主要是因为参数类型问题导致的情况比较多,下面来分析一下. 参数类型:缺省参数,关键字参数,不定长位置参数,不定长关键字参数. 其实总共可以分为 位置参数和关键字参 ...

  3. Python进阶(三)----函数名,作用域,名称空间,f-string,可迭代对象,迭代器

    Python进阶(三)----函数名,作用域,名称空间,f-string,可迭代对象,迭代器 一丶关键字:global,nonlocal global 声明全局变量: ​ 1. 可以在局部作用域声明一 ...

  4. 学以致用三十二-----python中函数的括号使用

    一直以来对python中函数括号的使用,有点分不清楚,到底什么时候用括号,什么时候不用括号,造成了很大看困惑. 今天来总结下. class aaa(): y = 'you' def __init__( ...

  5. Python虚拟机函数机制之参数类别(三)

    参数类别 我们在Python虚拟机函数机制之无参调用(一)和Python虚拟机函数机制之名字空间(二)这两个章节中,分别PyFunctionObject对象和函数执行时的名字空间.本章,我们来剖析一下 ...

  6. python的函数

    函数一词起源于数学,但是在编程中的函数和数学中的有很大不同.编程中的函数式组织好的,可重复使用的,用于实现单一功能或相关联功能的代码块. 我们在学习过程中已经使用过一些python内建的函数,如pri ...

  7. Python回调函数用法实例详解

    本文实例讲述了Python回调函数用法.分享给大家供大家参考.具体分析如下: 一.百度百科上对回调函数的解释: 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函 ...

  8. Python之函数与变量

    本节内容 函数介绍及其作用 函数的定义与调用 函数的参数说明 全局变量与局部变量 值传递和引用传递 一.函数的介绍及其作用 编程语言中的函数与数学中的函数是有区别的:数学中的函数有参数(输入),就会有 ...

  9. Python基础-函数篇

    本节内容 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数  函数与函数式编程 1.面向对象: 华山派-- ...

  10. 【C++实现python字符串函数库】strip、lstrip、rstrip方法

    [C++实现python字符串函数库]strip.lstrip.rstrip方法 这三个方法用于删除字符串首尾处指定的字符,默认删除空白符(包括'\n', '\r', '\t', ' '). s.st ...

随机推荐

  1. 通过ajax提交到url路由

    $regBoxform.find('button').on('click', function(){ /*通过ajax提交请求*/ $.ajax({ type:'post', /*用post 方式提交 ...

  2. 事后调试.ZC资料

    1.查了一下,Delphi 程序 可以生成 map文件,可以用来 根据崩溃的内存报错 定位出错的代码位置 2.但是,Delphi程序 无法再崩溃的时候 生成dump文件 (这个不一定,研究了再说.记得 ...

  3. ElasticSearch介绍与安装

    什么是ES? 1基于Apache Lucene构建的开源搜索引擎 2采用java编写,提供简单易用的RESTFul API 3轻松的横向扩展,可支持PB级的结构化或非结构化数据处理 ES的应用场景? ...

  4. WPF 回车转Tab实现跳转

    1.重写窗体的KeyDown事件 protected override void OnKeyDown(KeyEventArgs e) { if (e.Key == Key.Enter) { // Mo ...

  5. 1-10 RHLE7 系统进程管理

    1.1-Linux进程管理 程序.进程.线程 程序:一组指令的集合    QQ 进程:程序的执行就是进程.也可以把进程看成一个独立的程序,在内存中有其对应的代码空间和数据空间,一个进程所拥有的数据和代 ...

  6. CentOS上部署Django+Nginx+Uwsgi环境

    在CentOS上部署Django+Nginx+Uwsgi环境 奇谭  2016-09-01 评论  Linux  python django nginx uwsgi VirtualEnv的作用:创建隔 ...

  7. Hessian序列化

    当子类定义了和父类同名的属性时,经过hessian传输,会导致该属性值丢失.因为hessian发送二进制数据时,子类数据在前,父类数据在后.接收二进制数据时,子类数据在前,父类数据在后.所以对于同名字 ...

  8. 身份证真实性校验js、mini ui身份证长度正则验证

    身份证号码真实性校验 <input type="text" value="请输入身份证号" id="cards" ><bu ...

  9. 3.spring cloud eureka 高可用

    1.目的 防止某一台服务器宕机 通常通过多台EUREKA来为客户端进行注册,客户也进行注册 2.开启三台EUREKA 三天EUREKA分别对应端口 8761 8762 8763 配置文件如下 EURE ...

  10. 【51nod-1042】数字0-9的数量

    给出一段区间a-b,统计这个区间内0-9出现的次数.   比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次. Inp ...