part5-1 Python 函数递归函数、参数传递方式、变量作用域、局部函数

函数的特点:
(1)、使用 def 关键字定义,有函数名。使用 lambda 定义的函数除外。
(2)、一个函数通常执行一个特定任务,可多次调用,因此函数是代码利用的重要手段。
(3)、函数调用时可以传递0个或多个参数。
(4)、函数有返回值。

一、 函数基础

函数是 Python 程序的重要组成单位,一个 Python 程序可以由多个函数组成。

1、 理解函数
在定义函数时,至少需要清楚下面3点:
(1)、函数有几个需要动态变化的数据,这些数据应该被定义成函数的参数。
(2)、函数需要返回几个重要的数据,这些数据应该被定义成返回值。
(3)、函数的内部实现过程。

函数的定义要比函数的调用难很多。对于实现复杂的函数,定义本身就很费力,所以有时实现不出来也正常。

2、 定义函数和调用函数
函数定义语法格式如下:
1 def function_name(arg1,arg2,...): 2     # 函数体(由0条或多条代码组成)
3     [return [返回值]]

语法格式说明如下:
(1)、函数声明必须使用 def 关键字。
(2)、函数名是一个合法的标识符,不要使用 Python 保留的关键字;函数名可由一个或多个有意义的单词连接而成,单词之间用下划线分隔,单词的字母全部用小写。
(3)、形参列表,用于定义该函数可以接收的参数。形参列表由多个形参名组成,形参之间用英文逗号分隔。在定义函数指定了形参,调用该函数时必须传入对应的参数值,即谁调用函数,谁负责为形参赋值。

函数被调用时,既可以把调用函数的返回值赋值给指定变量,也可以将函数的返回值传给另一个函数,作为另一个函数的参数。

函数中 return 语句可以显式地返回一个值,return 语句返回的值既可是有值的变量,也可是一个表达式。

3、 为函数提供文档
Python 有内置的 help() 函数可查看其他函数的帮助文档。在编写函数时,把一段字符串放在函数声明之后、函数体之前,这段字符串将被作为函数的一部分,这个文档就是函数的说明文档。

函数可通过 help() 函数查看函数的说明文档,也可通过函数的 __doc__ 属性访问函数的说明文档。示例如下:
 1 def max_num(x,y):
 2     """
 3     获取两个数值中较大数的函数
 4     max_num(x,y)
 5         返回x、y两个参数之间较大的那个数
 6     """
 7     return x if x > y else y
 8 # 使用 help() 函数和 __doc__ 属性查看 max_num 的帮助文档
 9 help(max_num)
10 print(max_num.__doc__)

运行这段代码时,可以看到输出的帮助文档信息。

4、 多个返回值
如果函数有多个返回值,可将多个值包装成列表或字典后返回。也可直接返回多个值,这时 Python 会自动将多个返回值封装成元组。
1 # 定义函数
2 def foo(x,y) 3     return x + y,x - y 4 # 调用函数
5 a1 = foo(10,5)     # 函数返回的是一个元组,变量a1 也就是一个元组

也可使用 Python 提供的序列解包功能,直接用多个变量接收函数返回的多个值,例如:
a2,a3 = foo(10,5)

5、 递归函数
在函数体内调用它自身,被称为函数递归。函数递归包含一种隐式的循环,它会重复执行某段代码,这种重复执行无须循环控制。

现假设有一个数列,f(0)=1,f(1)=4,f(n+2)=2*f(n+1)+f(n),n是大于0的整数,求f(10)的值。这道题用递归函数计算,代码如下:
 1 def f(n):  2     if n == 0:  3         return 1
 4     elif n == 1:  5         return 4
 6     else:  7         # 在函数体内调用其自身,就是递归函数
 8         return 2 * f(n - 1) + f(n - 2)  9 
10 print(f(10))        # 输出:10497

在这段代码中,f() 函数体中再次调用了 f() 函数,就是递归函数。调用形式是:
return 2 * f(n - 1) + f(n - 2)

对于 f(10)等于 2*f(9)+f(8),其中f(9)又等于2*f(8)+f(7)······,以此类推,最终计算到 f(2)等于2*f(1)+f(0),即f(2)是可计算的,这样递归的隐式循环就有结束的时候,然后一路反算回去最后得到 f(10) 的值。

在上面这个递归函数中,必须在某个时刻函数的返回值是确定的,即不再调用它自身;否则,这种递归就变成了无穷递归,类似于死循环。所以,在定义递归时的一条重要规定是:递归一定要向已知的方向进行

现在将这个数列的已知条件改为这样,已知:f(20)=1,f(21)=4,f(n+2)=2*f(n+1)+f(n),其中n是大于0的整数,求f(10)的值。此时f()函数体就应该改为如下形式:
1 def f(n): 2     if n == 20: 3         return 1
4     elif n == 21: 5         return 4
6     else: 7         return f(n + 2) - 2 * f(n + 1) 8 print(f(10))        # 输出:-3771

在这次的 f() 函数中,要计算 f(10) 的值时,f(10)等于f(12)-2*f(11),而 f(11)等于f(13)-2*f(12)······,以此类推,直到 f(19)等于f(21)-2*f(20),此时得到 f(19)的值,然后依次反算到f(10)的值。

递归在编程中非常有用,例如程序要遍历某个路径下的所有文件,但这个路径下的文件夹的深度是未知的,此时就可用递归来实现这个需求。

总结:在一个函数的函数体中调用自身,就是递归函数。递归一定要向已知的方向进行。

二、 函数的参数

1、关键字(keyword)参数
按照形参位置传入的参数称为位置参数。如果根据位置参数的方式传入参数值,则必须严格按照定义函数时指定的顺序来传入参数值;也
可根据参数名来传入参数值,此时无须遵守定义形参的顺序,这种方式就是关键字(keyword)参数。示例如下:
 1 # 定义一个计算周长的函数 girth,接收两个形参
 2 def girth(length,width):  3     print("length:",length)  4     print("width:",width)  5     return 2 * (length + width)  6 # 传统调用函数方式,根据位置传入参数值
 7 print(girth(3,5.5))  8 # 根据关键字参数传入参数值,使用关键字时,参数位置可以交换
 9 print(girth(width=5.5,length=3)) 10 # 部分用关键字,部分用位置参数,位置参数必须在关键字参数前面
11 print(girth(3,width=5.5))

在使用关键字参数调用函数时要注意,在调用函数时同时使用位置参数和关键字参数时,位置参数必须位于关键字参数的前面。也就是
关键字参数后面只能是关键字参数。

2、 参数默认值
在定义函数时,可以为一个或多个形参指定默认值,这样在调用函数时可以省略为该形参传入参数值,直接使用该形参的默认值。示例如下:
 1 # 为参数指定默认值
 2 def say_hi(name=michael,message="欢迎学习使用Python!"):  3     print("hello,",name)  4     print("消息是:",message,sep="")  5 # 第一次调用:使用默认参数调用函数
 6 say_hi()  7 # 第二次调用:传入1个位置参数时,默认传给第一个参数
 8 say_hi(jack)  9 # 第三次调用:传入2个位置参数
10 say_hi(stark,欢迎使用 C 语言!) 11 # 使用关键字参数指明要传给哪个参数
12 say_hi(message="欢迎使用 Linux 系统!") 13 
14 输出如下所示: 15 hello,michael 16 消息是:欢迎学习使用Python! 17 hello,jack 18 消息是:欢迎学习使用Python! 19 hello,stark 20 消息是:欢迎使用 C 语言! 21 hello,michael 22 消息是:欢迎使用 Linux 系统!

从这个程序可知,当只传入一个位置参数时,由于该参数位于第一位,系统会将该参数值传给 name 参数。

在Python 中,关键字参数必须位于位置参数后面,所以下面把关键字参数放在前面是错误的做法:
say_hi(name=‘stark‘,‘欢迎使用 C 语言!‘)
这样调用函数时,报 “positional argument follows keyword argument” 错误。

在调用函数时,也不能简单的交换两个参数的位置,下面对函数的调用方式同样是错误的:
say_hi(‘欢迎使用 C 语言!‘,name=‘stark‘)
因为第一个字符串没有指定关键字参数,因此使用位置参数为 name 参数传入参数值,第二个参数使用关键字参数的形式再次为 name 参数传入参数值,这样造成两个参数值都会传给 name 参数,程序为 name 参数传入了多个参数值。因此错误提示:say_hi() got multiple values for argument ‘name‘

Python 要求在调用函数时关键字参数必须位于位置参数后面,因此在定义函数时指定默认值的参数(关键字参数)必须在没有默认值的参数之后。例如:
1 def foo(a,b=10): pass  # 有默认值的参数在没有默认值的参数后面
2 下面这些调用函数的方法都是正确的: 3 foo(5) 4 foo(a=5,b=4) 5 foo(5,4) 6 foo(a=python)

3、 参数收集(个数可变的参数)
在定义函数时,形参前面加一个星号(*)表示该参数可接收多个参数值,多个参数值被当成元组传入。示例如下:
 1 def my_test(a,*args):  2     """测试支持参数收集的函数"""
 3     print(args)  4     # args 参数被当成元组处理
 5     for s in args:  6         print(s)  7     print(a)  8 my_test(123,python,linux,C)  9 
10 输出如下所示: 11 (python,C) 12 python 13 linux 14 C 15 123

从输出可知,在调用 my_test() 函数时,args 参数可以传入多个字符串作为参数值,参数收集的本质就是一个元组,将传给 args 的多个值收集成一个元组。

对于个数可变的形参可以处于形参列表的任意位置,但是函数最多只能有一个“普通”参数收集的形参。例如下面这样:
def my_test(*args,a): pass

在定义函数时,把个数可变的形参放在前面。那么在调用该函数时,如果要给后面的参数传入参数值,就必须使用关键字参数;否则,程序会把所传入的多个值都当成是传给 args 参数的。

另外,Python 还可以将关键字参数收集成字典,这时在定义函数时,需要在参数前面加两个星号(**)。一个函数可同时包含一个支持“普通”参数收集的参数和一个支持关键字参数收集的参数。示例如下:
1 def bar(a,b,c=5,*args,**kwargs): pass
2 bar(1,2,3,"python","linux",name=stark,age=30)

在调用 bar() 函数时,前面的1、2、3会传给普通参数a、b、c;后面紧跟的两个参数由 args 收集成元组;最后的两个关键字参数被kwargs 收集成字典。这个 bar() 函数中,c 参数的默认值基本上不能发挥作用。要使 c 参数的默认起作用,可用下面方式调用函数:
bar(1,age=30)

4、 逆向参数收集
逆向参数收集指的是在程序中将已有的列表、元组、字典等对象,将其拆分后传给函数的参数。逆向参数收集需要在传入的列表、元组等参数之前添加一个星号,在字典参数之前添加两个星号。示例如下:
1 def bar(s1,s2): 2     print(s1) 3     print(s2) 4 s = ab
5 bar(*s) 6 ss = ("python","linux") 7 bar(*ss) 8 ss_dict = {"s1": "michael","s2": 25} 9 bar(**ss_dict)

在这个 bar() 函数中,定义时声明了两个形参,在调用函数时,使用一个星号拆分序列(字符串、列表、元组)时,拆分出来的个数也应和形参的个数一样多。使用两个星号传递字典参数时,则要求字典的键与函数的形参名保持一致,并且字典的键值对与函数的形参个数也要一致。

即使支持收集的参数,如果要将一个字符串或元组传给该参数,同样也需要使用逆向收集。示例如下:
1 def bar(s1,*s2): 2     print(s1) 3     print(s2) 4 s = abcd
5 bar("py",*s) 6 ss = ("python","linux") 7 bar("java",*ss)

这次的函数调用中,可以使用一个星号拆分序列,序列的元素个数可以有多个。但是不能使用两个星号拆分字典后向其传参数。实际上,在调用函数时,只传递一个拆分后的序列参数也是可以的,例如:
bar(*s)
这时程序会将 s 进行逆向收集,其中字符串的第一个元素传给 s1 参数,后面的元素传给 s2 参数。如果不使用逆向收集(不在序列参数前使用星号),则会将整个序列作为一个参数,而不是将序列的元素作为多个参数。例如:
bar(s)
这次调用没有使用逆向收集,因此 s 整体作为参数值传给 s1 参数。

字典也支持逆向收集,字典以关键字参数的形式传入。这要求字典的键与函数的形参名一致,并且字典的键值对数量与函数的形参数量一样多。示例在前面已提到。

5、 函数的参数传递机制
Python 中函数的参数传递机制都是“值传递”,就是将实际参数值的副本(复制品)传入函数,而参数本身不会受到任何影响。示例如下:
 1 def swap(a,b):  2     a,b = b,a  3     print("在swap函数里,a的值是%s; b 的值是%s" % (a,b))  4 a = 10
 5 b = 20
 6 swap(a,b)  7 print("变换结束后,变量 a 的值是%s;变量 b 的值是%s。" % (a,b))  8 
 9 运行代码,输出如下: 10 在swap函数里,a的值是20; b 的值是10 11 变换结束后,变量 a 的值是10;变量 b 的值是20。

在这段代码中,swap() 函数中交换了变量a、b 的值,在函数内输出的是交换后的值,在函数外部仍然是未交换时的值。由此可知,程序中实际定义的变量 a 和 b,并不是 swap() 函数里的 a 和 b。在 swap() 函数里的 a 和 b 是主程序中变量 a 和 b 的复制品。

在主程序中调用 swap() 函数时,系统分别为主程序和 swap() 函数分配两块栈区,用于保存它们的局部变量。将主程序中的 a、b 变量作为参数值传入 swap() 函数,实际上是在 swap() 函数栈区中重新产生了两个变量 a、b,并将主程序栈区的 a、b 变量的值分别赋值给 swap() 函数栈区中的 a、b 参数。此时系统存在两个 a 变量、两个 b 变量,只是存在于不同的栈区中。

参数值传递实质:当系统开始执行函数时,系统对形参执行初始化,就是把实参变量的值赋给函数的形参变量,在函数中操作的并不是实际的实参变量。

要注意的是,如果参数本身是可变对象(比如列表、字典等),此时同样也是采用的值传递方式,但是在函数中变量存储的是可变对象的内存地址,因此在函数中对可变对象进行修改时,修改结果会反应到原始的可变对象上。

关于参数传递机制的总结:
(1)、不管什么类型的参数,在 Python 函数中对参数直接使用 “=” 符号赋值是没用的,直接使用 “=” 符号赋值并不能改变参数。
(2)、如果要让函数修改某些数据,则可以通过把这些数据包装成列表、字典等可变对象,然后把列表、字典等可变对象作为参数传入函数,在函数中通过列表、字典的方法修改它们。这样才能改变这些数据。

6、 变量作用域
程序中定义的变量有作用范围,叫做作用域。变量分为两种:
(1)、局部变量:在函数中定义的变量,包括参数,都被称为局部变量。
(2)、全局变量:在函数外面、全局范围内定义的变量,被称为全局变量。

函数在执行时,系统为函数分配一块临时内存空间,所有局部变量被保存在这块临时空间内。函数执行完成后,这块临时内存空间就被释放,同时局部变量就失效。所以离开函数后,就不能访问局部变量。

全局变量可以在所有函数内被访问到。不管是局部变量还是全局变量,变量和它们的值就像一个“看不见”的字典,变量名是 key,变量值是字典的 value。Python 提供下面三个工具函数来获取指定范围内的“变量字典”:
(1)、globals():返回全局范围内所有变量组成的“变量字典”。
(2)、locals():返回当前局部范围内所有变量组成的“变量字典”。
(3)、vars(object):获取在指定对象范围内所有变量组成的“变量字典”。不传入 object 参数,vars() 和 locals() 作用完全相同。

globals()和locals()的区别与联系:
(1)、locals() 总是获取当前局部范围内所有变量组成的“变量字典”。因此,在全局范围内(在函数之外)调用locals() 函数,同样会获取全局范围内所有变量组成的“变量字典”;而globlas() 无论在哪里执行,总是获取全局范围内所有变量组成的“变量字典”。
(2)、通常使用 locals()和globals()获取的“变量字典”只应该被访问,不应该被修改。实际上不管使用globlas()还是locals()获取的全局范围内的“变量字典“,都可以被修改,则这种修改会真正修改全局变量本身;但通过locals()获取的局部范围内的”变量字典“,即使对它修改也不会影响局部变量。

下面用代码理解 locals() 和 globlas() 函数的使用:
 1 def test():  2     name = michael
 3     print(name)         # 输出:michael
 4     # 访问函数局部范围内的”变量字典“
 5     print(locals())     # 输出:{‘name‘: ‘michael‘}
 6     # 通过函数局部范围内的”变量数组“访问 name 变量
 7     print(locals()[name])     # 输出:michael
 8     # 通过 locals() 函数修改局部变量的值,即使修改了也不会对局部变量有什么影响
 9     locals()[name] = stark
10     # 再次访问 name 变量的值
11     print("modify: ",locals()[name])     # 输出:modify: michael
12     # 通过 globlas() 函数修改全局变量 x 的值
13     globals()[x] = 10
14 x = 1
15 y = 2
16 # 在全局范围内调用 globals() 函数和 locals() 函数,访问的是全局变量的”变量字典",两个函数输出的结果一样
17 print(globals())    # 输出:{...,‘x‘: 1,‘y‘: 2}
18 print(locals())     # 输出:{...,‘y‘: 2}
19 # 在全局范围内直接使用 globlas 和 locals 函数访问全局变量
20 print(globals()[x])       # 输出:1
21 print(locals()[x])        # 输出:1
22 # 在全局范围地内使用 globlas 和 locals 函数修改全局变量的值
23 globals()[x] = 30
24 locals()[y] = 20
25 # 从输出可知,在全局范围内,使用 globlas 和 locals 函数修改全局变量的值都会修改成功
26 print("modify: ",globals()[x])   # modify: 30
27 print("modify: ",locals()[y])    # modify: 20
28 
29 test()      # 在函数内部使用 globals 函数修改全局变量的值也会修改成功
30 print("modify two: ",globals()[x])   # modify two: 10

从函数输出可知,locals() 函数用于访问特定范围内的所有变量组成的”变量字典“,但是不能修改特定范围内”变量字典“中变量的值。在全局范围不管使用 locals() 函数还是 globals() 函数都可以修改全局范围内”变量字典“中变量的值。globals() 函数在特定范围内也可以修改全局范围内”变量字典“中变量的值。

全局变量可以在所有函数内被访问,但是在函数内定义了与全局变量同名的变量时,此时全局变量会被局部变量遮蔽。示例如下:
1 name = michael
2 def test():
3     # 直接访问 name  的全局变量
4     print(name)
5     name = stark
6 test()

运行这段代码,此时程序会报错,错误信息是:UnboundLocalError: local variable ‘name‘ referenced before assignment。错误信息提示在函数内访问的 name 变量还未定义,这是由于在 test() 函数中增加了 ”name=‘start‘“ 这行代码造成的。

Python 语法规定:在函数内部对不存在的变量赋值时,默认就是重新定义新的局部变量。因此这行 ”name=‘start‘“ 相当于重新定义了 name 局部变量,这样 name 全局变量就被遮蔽了,所以代码会报错。为了让程序不报错,可用两种方式修改上面代码。

第一种方式:访问被遮蔽的全局变量
在 test() 函数中希望 print 语句仍然能访问 name 全局变量,并且要在 print 语句之后重新定义 name 局部变量,也就是在函数中可能访问被遮蔽的全局变量,此时可通过 globals() 函数来实现。代码修改如下:
1 name = michael
2 def test():
3     # 直接访问 name  的全局变量
4     print(globals()[name])    # 输出:michael
5     name = stark‘        # 定义局部变量
6 test()
7 print(name)                     # 输出:michael

第二种方式:在函数中声明全局变量
为避免在函数中对全局变量赋值(不是重新定义局部变量),可使用 globals 语句来声明全局变量。代码可修改为如下形式:
1 name = michael
2 def test():
3     # 先声明 name 是全局变量,后面的赋值语句不会重新定义局部变量,而是直接修改全局变量
4     global name
5     # 直接访问 name 全局变量
6     print(name)             # 输出:michael
7     name = stark        # 修改全局变量
8 test()
9 print(name)                 # 输出:stark

在test() 函数中的”global name“ 声明 name 为全局变量,后面对 name 赋值的语句只是对全局变量赋值,不是重新定义局部变量。

三、 局部函数

Python 支持在函数体内定义函数,这种放在函数体内定义的函数称为局部函数。默认情况下,局部函数对外部是隐藏的,局部函数只能在其封闭(enclosing)函数内有效,其封闭函数也可以返回局部函数,以便程序在其他作用域中使用局部函数。局部函数示例:
 1 def foo(type,nn):  2     """定义一个函数,该函数包含局部函数"""
 3     def square(n):  4         """定义一个计算平方的局部函数"""
 5         return n * n  6     def cube(n):  7         """定义一个计算立方的局部函数"""
 8         return n * n * n  9     def factorial(n): 10         """定义一个计算阶乘的局部函数"""
11         result = 1
12         for i in range(2,n + 1): 13             result *= i 14         return result 15     # 调用局部函数
16     if type == square: 17         return square(nn) 18     elif type == cube: 19         return cube(nn) 20     else: 21         return factorial(nn) 22 print(foo(square,5))         # 输出:25
23 print(foo(cube,3))           # 输出:27
24 print(foo(‘‘,3))               # 输出:6

这里的 foo() 函数体内定义了3个局部函数,foo() 函数根据参数选择调用不同的局部函数。如果封闭函数(foo())没有返回局部函数,那么局部函数只能在封闭函数内部调用。例如上面的 foo() 函数。

另一种情况是,封闭函数将局部函数返回,且程序使用变量保存了封闭函数的返回值,那么这些局部函数的作用域就会被扩大,程序可通过该变量自由的调用它们,就像它们是全局函数一样。

局部函数内的变量也会遮蔽它所在函数内的局部变量。示例如下:
1 def foo(): 2     # 局部变量 name
3     name = michael
4     def bar(): 5         # 访问 bar 函数所在 foo 函数内的 name 局部变量
6         print(name)         # michael
7         name = stark
8  bar() 9 foo()
运行这段代码,出现错误提示“UnboundLocalError: local variable ‘name‘ referenced before assignment”。这错误是由于局部变量遮蔽局部变量导致的,在 bar() 函数中定义的 name 局部变量遮蔽了它所在 foo() 函数内的 name 局部变量,因此导致程序中 print 语句代码报错。

为了使 bar() 函数内的“name = ‘stark‘” 赋值语句不是定义新的局部变量,只是访问它所在 foo() 函数内的 name 局部变量,可使用Python 提供的 nonlocal 关键字,通过 nonlocal 语句即可声明访问赋值语句只是访问该函数所在函数内的局部变量。示例如下:
 1 def foo():  2     # 局部变量 name
 3     name = michael
 4     def bar():  5         # 访问 bar 函数所在 foo 函数内的 name 局部变量
 6  nonlocal name  7         print(name)         # michael
 8         name = stark
 9  bar() 10 foo()
在 foo() 函数内增加 “nonlocal name” 语句后,在 bar() 函数中的 “name = ‘stark‘” 就不再是定义新的局部变量,而是访问它所在函数(foo())内的 name 局部变量。

nonlocal 的功能和 global 功能大致相似,区别是 global 用于声明全局变量,而 nonlocal 用于声明访问当前函数所在函数内的局部变量。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用OpenCV实现视频去抖 整体步骤: 设置输入输出视频 寻找帧之间的移动:使用opencv的特征检测器,检测前一帧的特征,并使用Lucas-Kanade光流算法在下一帧跟踪这些特征,根据两组点,将前一个坐标系映射到当前坐标系完成刚性(欧几里得)变换,最后使用数组纪录帧之间的运动。 计算帧之间的平
前言 对中文标题使用余弦相似度算法和编辑距离相似度分析进行相似度分析。 准备数据集part1 本次使用的数据集来源于前几年的硕士学位论文,可根据实际需要更换。结构如下所示: 学位论文题名 基于卷积神经网络的人脸识别研究 P2P流媒体视频点播系统设计和研究 校园网安全体系的设计与实现 无线传感器网络中
前言 之前尝试写过一个爬虫,那时对网页请求还不够熟练,用的原理是:爬取整个html文件,然后根据标签页筛选有效信息。 现在看来这种方式无疑是吃力不讨好,因此现在重新写了一个爬取天气的程序。 准备工作 网上能轻松找到的是 101010100 北京这种编号,而查看中国气象局URL,他们使用的是北京545
前言 本文使用Python实现了PCA算法,并使用ORL人脸数据集进行了测试并输出特征脸,简单实现了人脸识别的功能。 1. 准备 ORL人脸数据集共包含40个不同人的400张图像,是在1992年4月至1994年4月期间由英国剑桥的Olivetti研究实验室创建。此数据集包含40个类,每个类含10张图
前言 使用opencv对图像进行操作,要求:(1)定位银行票据的四条边,然后旋正。(2)根据版面分析,分割出小写金额区域。 图像校正 首先是对图像的校正 读取图片 对图片二值化 进行边缘检测 对边缘的进行霍夫曼变换 将变换结果从极坐标空间投影到笛卡尔坐标得到倾斜角 根据倾斜角对主体校正 import
天气预报API 功能 从中国天气网抓取数据返回1-7天的天气数据,包括: 日期 天气 温度 风力 风向 def get_weather(city): 入参: 城市名,type为字符串,如西安、北京,因为数据引用中国气象网,因此只支持中国城市 返回: 1、列表,包括1-7的天气数据,每一天的分别为一个
数据来源:House Prices - Advanced Regression Techniques 参考文献: Comprehensive data exploration with Python 1. 导入数据 import pandas as pd import warnings warnin
同步和异步 同步和异步是指程序的执行方式。在同步执行中,程序会按顺序一个接一个地执行任务,直到当前任务完成。而在异步执行中,程序会在等待当前任务完成的同时,执行其他任务。 同步执行意味着程序会阻塞,等待任务完成,而异步执行则意味着程序不会阻塞,可以同时执行多个任务。 同步和异步的选择取决于你的程序需
实现代码 import time import pydirectinput import keyboard if __name__ == '__main__': revolve = False while True: time.sleep(0.1) if keyboard.is_pr
本文从多个角度分析了vi编辑器保存退出命令。我们介绍了保存和退出vi编辑器的命令,以及如何撤销更改、移动光标、查找和替换文本等实用命令。希望这些技巧能帮助你更好地使用vi编辑器。
Python中的回车和换行是计算机中文本处理中的两个重要概念,它们在代码编写中扮演着非常重要的角色。本文从多个角度分析了Python中的回车和换行,包括回车和换行的概念、使用方法、使用场景和注意事项。通过本文的介绍,读者可以更好地理解和掌握Python中的回车和换行,从而编写出更加高效和规范的Python代码。
SQL Server启动不了错误1067是一种比较常见的故障,主要原因是数据库服务启动失败、权限不足和数据库文件损坏等。要解决这个问题,我们需要检查服务日志、重启服务器、检查文件权限和恢复数据库文件等。在日常的数据库运维工作中,我们应该时刻关注数据库的运行状况,及时发现并解决问题,以确保数据库的正常运行。
信息模块是一种可重复使用的、可编程的、可扩展的、可维护的、可测试的、可重构的软件组件。信息模块的端接需要从接口设计、数据格式、消息传递、函数调用等方面进行考虑。信息模块的端接需要满足高内聚、低耦合的原则,以保证系统的可扩展性和可维护性。
本文从电脑配置、PyCharm版本、Java版本、配置文件以及程序冲突等多个角度分析了Win10启动不了PyCharm的可能原因,并提供了解决方法。
本文主要从多个角度分析了安装SQL Server 2012时可能出现的错误,并提供了解决方法。
Pycharm是一款非常优秀的Python集成开发环境,它可以让Python开发者更加高效地进行代码编写、调试和测试。在Pycharm中设置解释器非常简单,我们可以通过创建新项目、修改项目解释器、设置全局解释器等多种方式进行设置。
Python中有多种方法可以将字符串转换为整数,包括使用int()函数、try-except语句、正则表达式、map()函数、ord()函数和reduce()函数。在实际应用中,应根据具体情况选择最合适的方法。
本文介绍了导入CSV文件的多种方法,包括使用Excel、Python和R等工具。同时,还介绍了导入CSV文件时需要注意的一些细节和问题。CSV文件是数据处理和分析中不可或缺的一部分,希望本文能够对读者有所帮助。
mongodb是一种新型的数据库,它采用了面向文档的数据模型,具有灵活性、高性能和高可用性等优势。但是,mongodb也存在数据结构混乱、安全性和学习成本高等问题。
当Python运行不了时,我们应该从代码、Python环境、操作系统和硬件设备等多个角度来排查问题,并采取相应的解决措施。