Home > Article > Backend Development > Learn Python Chapter 3__Functional programming, recursion, built-in functions
1. Functional programming
Creating functions
A functional formula consists of the keyword def, the function name, brackets and colons, and the parameters in the brackets. When you want to execute the function At this time, you only need to write the function name and brackets
Format: def function (parameter) Next, create a function
#!/usr/bin/env python # -*- coding:utf-8 -*- #创建函数 def print_str(): print("Hello World") #调用函数 print_str()
The first function
The scope of the variable
Let’s look at an example. In the following code, we first set the variable a="haha ” Then put a = “heihei” in the function and finally execute this function and output the result of variable a
We found out why a is not equal to “heihei”, but the “haha” we assigned before. This phenomenon we Immediately reveal the secret
#!/usr/bin/env python # -*- coding:utf-8 -*- a = "haha" #创建函数 def print_str(): a = "heihei" print("Hello World") #调用函数 print_str() print("我是变量a:",a)
The scope of variables Example 1
Global variables With local variables
It is obvious that the scope of a variable is the scope within which the variable takes effect. If it is outside this scope, it cannot be used
Global variables: Usually global variables survive the end of the script. And all functions can access it
Local variables: They can only be called within the function where the local variable is located, and unless the local variable is declared as a global variable, other functions cannot be called, and local variables
When the function is executed, it will no longer exist
#!/usr/bin/env python # -*- coding:utf-8 -*- a = "haha" #创建函数 def print_str(): a = "heihei" print("我是局部变量a:",a) #调用函数 print_str() print("我是全局变量a:",a)
##Global variables and local variables
#!/usr/bin/env python # -*- coding:utf-8 -*- a = "haha" #创建函数 def print_str(): global a a = "heihei" print("我是局部变量a:",a) #调用函数 print_str() print("我是全局变量a:",a)
Passing parameters The function is relatively simple to use and easy to understand, but the parameters change more. The parameters are in the function brackets. The parameters can receive strings, numbers, and can also receive dictionaries and lists. And when calling, we can also specify which parameter to assign what value
#!/usr/bin/env python # -*- coding:utf-8 -*- #创建函数 def print_str(Name,Age,Aender): print(''' Name:%s Age:%s Aender:%s '''%(Name,Age,Aender)) #用户输入 in_name = input("请输入你的名字:") in_age = input("请输入你的年龄:") in_aender = input("请输入你的性别:") #固定位置传参 print_str(in_name,in_age,in_aender) print("----------------------------------") #不固定位置传参 print_str(in_name,Aender=in_aender,Age=in_age)
##Passing parameters
What should we do when we want to pass in a list or dictionary?
#!/usr/bin/env python # -*- coding:utf-8 -*- def print_str(lists): if type(lists) == list: print(''' Name:%s Age:%s Aender:%s '''%(lists[0],lists[1],lists[2])) else: print(''' Name:%s Age:%s Aender:%s '''%(lists["name"],lists["age"],lists["aenber"])) #传入列表 userlist = ["Ben","22","Man"] print_str(userlist) print("----------------------------------") #传入字典 userdict = {"name":"Ben","age":"022","aender":"Man"} print_str(userlist)
Pass in a dictionary or list
Default parameters
You can also set default parameters in the function. The default parameter means that you can pass a value or no value for this parameter. When no value is passed, the parameter is equal to the default value
#!/usr/bin/env python # -*- coding:utf-8 -*- def print_str(lists,Country="China"): if type(lists) == list: print(''' Name:%s Age:%s Aender:%s country:%s '''%(lists[0],lists[1],lists[2],Country)) else: print(''' Name:%s Age:%s Aender:%s country:%s '''%(lists["name"],lists["age"],lists["aenber"],Country)) #传入列表 userlist = ["Ben","22","Man"] print_str(userlist) print("----------------------------------") #传入字典 userdict = {"name":"Ben","age":"022","aender":"Man"} print_str(userlist,"America")
Default parameters
Non-fixed parameters
The meaning of non-fixed parameters is that they can receive any number of values. The function is used when it is not sure how many values the user wants to pass in. Of course, we can not pass parameters when calling a function with only non-fixed parameters.
Non-fixed parameters are divided into one * and two *. *args will turn the incoming parameters into ancestors, and **kwargs will turn the incoming parameters into dictionaries. Of course, *ages can be other names. However, it is best to use *args and **kwargs
#!/usr/bin/env python # -*- coding:utf-8 -*- def print_str(*args,**kwargs): print("我是*",args) print("我是**",kwargs) #传入列表 userlist = ["Ben","22","Man"] print_str(userlist,"America") print("----------------------------------") #传入字典 print_str(A = "1",B = "2")
##Non-fixed parameters
Since formal parameters can take * and **, then actual parameters can also take * and **, then * is used with lists, and ** is used with dictionaries! #!/usr/bin/env python
# -*- coding:utf-8 -*-
def print_str(*args,**kwargs):
print("我是*",args)
print("我是**",kwargs)
#传入列表
userlist = ["Ben","22","Man"]
print_str(*userlist)
print("----------------分隔符----------------")
#传入字典
userdict = {"name":"Ben","age":"022","gender":"Man"}
print_str(**userdict)
Deparameterization
If the actual parameter is *, the list will be decomposed into " Ben","22","Man" is passed into the function one by one, and ** will decompose the dictionary into name="Ben",age="022",gender="Man" This key-value pair is passed into the function.
注!当普通参数和默认参数和非固定参数结合使用的时候,要遵循一个顺序,普通参数在默认参数前面,默认参数在非固定参数前面
返回值
在正常使用函数的时候,函数是可以把函数内部处理的结果返回给函数调用者的,在没有返回值得函数中会保留None传给函数调用者,返回值可以返回序列等
在函数执行的时候遇到return函数会停止执行,并返回结果
#!/usr/bin/env python # -*- coding:utf-8 -*- #创建函数 def print_str(Age): if int(Age) <= 30: return "你才%s啊!真年轻"%(Age) else: return "你都%s啦!老家伙"%(Age) in_age = input("请输入你的年龄:") word = print_str(in_age) print(word)
return
嵌套函数
在函数内部也可以写函数,这样就是外层函数套着内侧函数,这种形式称之为嵌套函数,同理因为作用域的关系嵌套函数只能内部调用
return unction_2(stra)+"我是第二层\n" 就等于先 c = unction_2(stra) 然后 return c+"我是第二层\n"
def unction(stra): def unction_2(stra_2): return stra_2+"我是第三层\n" return unction_2(stra)+"我是第二层\n" r_str = unction("") print(r_str+"我是第一层")
嵌套函数
前面已经介绍了函数相关的知识,在函数中,函数可以调用其他的函数,并且函数还可以调用自身,利用这种特性我们可以完成一些特定的
操作,这种函数调用自身的形式就是递归
def recursion() :
return recursion()
在递归中不能像上面两行一样一直调用自身,这样一会程序就会崩溃,因为它永远的在调用就跟while死循环一样出不去,所以递归也需要进
判断给它出口
例子:阶乘
什么是阶乘,阶乘就是给一个自然数N,然后计算N的阶乘那么 N = 1x2x3x4....N ,这个就是阶乘,我们可以把它到过来看,
N = N x (n-1) x (n-2) x (n-3) ...... 1 一直乘到括号中的值等于1,既然知道了阶乘是什么,那么我们来写一个程序实现它
def factorial(n): for i in range(1,n): n *= i return n c = factorial(4) print(c)
阶乘非递归版本
剖析:上面的例子首先把n=4传入进去,然后通过 for i in range(1,4)让i分别等于1,2,3,然后进行 n*=i,我们可以看出这个for循环是循环3次的
第一次(n = n*i) n = 4*1 ,此时n还是等于4
第二次(n = 4*i) n = 4*2 此时n = 8
第三次(n = 8*i) n = 8*3 此时n等于24
此时for循环了3次所以结束了,通过return把n的结果返回,所以最终结果算出 4的阶乘等于24
递归版本
下面看递归版本的阶乘
def factorial(n) : if n == 1: return 1 else: return n * factorial(n-1) c = factorial(4) print(c)
阶乘递归版本
剖析:
首先c = factorial(4)开始执行函数,然后进行第一次判断 n == 1,显然第一层n不等于1,然后碰到return n * factorial(n-1),碰到return本来是要返回的,但是 factorial(n-1)
有调用了factiorial这个函数,因此进入了第二层
第二层因为上一层传入的参数是n-1,所以第二层的n是等于3的,然后判断,这一层的n也不等于1,然后又进入第三层
第三层n等于3,然后判断这一层的n还不等于1,然后又进入第四层
到第四层的时候这时的 n就等于1,所以触发了 return 1 不再调用函数了,所以就开始返回
返回第三层 return n * factorial(n-1) , 此时factorial(n-1) 就等于第四层return上去的1,所以第三层返回时就等于return n * 1(return 2 * 1),并且第三层n是等于2的
返回第二层factorial(n-1)就等于第三层return上去的2,并且第二层n是等于3的,return 3 * 2
返回第一层factorial(n-1)就等于第二层return上去的6,并且第一层n是等于4的,return 4 * 6
到此为止递归执行完毕,c就等于 4 * 6 c=24
匿名函数也叫lambda函数,函数没有具体的名称。语法:function name= lambda args(多个参数用逗号隔开): Expression(表达式,表达式的结果就是返回值)
先来看一个最简单例子:
#普通函数 def func(arg1,arg2): return arg1-arg2 #lambda函数 func_2 = lambda arg1,arg2: arg1-arg2 #传参执行 print(func(5,4)) print(func_2(5,4))
匿名函数
有认识,这个匿名函数和普通函数没有什么区别么,其实匿名函数就像三元运算一样,并且能够用lambda函数有几大优势
1、在一些不会再别的地方调用的函数,我们可以使用匿名函数,并且这样简化了代码,看起来更加整洁。
2、lambda函数将会搭配一些内置函数来使用(下面会涉及到)
在上面的示例中知道了函数可以调用函数本身,这种形式称之为递归,那么还可以将函数作为参数返回,这种形式就称之为闭包
闭包最大的好处就是即用即调,闭包对于安装计算,隐藏状态,以及在函数对象和作用域中随意地切换是很有用的!
#!/usr/bin/env python # -*- coding:utf-8 -*- def func(rate): count = [0] def add_func(arg): count[0] +=1 print("第%s次调用"%count[0]) arg = arg - arg*rate return arg return add_func closure = func(0.03) print(closure(1000)) print(closure(1100)) print(closure(1200))
闭包示例
例子中做了一个减去手续费后返回余额的功能,首先执行了func函数,将利率封装了进去,然后,func函数把它内部的函数进行了进行了返回
要知道当函数不加括号的时候是不执行的!,所以此时closoure就是 add_func 函数的内存地址,当想要使用这个功能的时候,直接把closoure加括号
并传入值即可执行。并且可以看到的是在全局作用域中执行,随时可以切换到局部作用域。
函数可以用来当做返回值,可以用调用自己本身,高阶函数就是函数的参数把另一个函数作为参数,这种函数就称之为高阶函数。
def func_1(num): return num+1 def func_2(num): return num-1 def func_main(num,func): # 可以简写成return func(num) results = func(num) return results results = func_main(10,func_1) print(results) print(func_main(10,func_2))
高阶函数
编写高阶函数,就是让函数的参数能够接收别的函数。
内置函数就是python中内置的一些方法
内置函数使用方法示例,详细介绍请参考
# !/usr/bin/env python # -*- coding:utf-8 -*- #返回数字的绝对值。 参数可以是整数或浮点数。 如果参数是复数,则返回其大小。 print(abs(-1.11)) #传入一个可被循环的元素,如果这个元素中有一个为False则都为假 # 0 空值 False 都为假 print(all([1,2,3])) #与all相反,只有一个为真,则为真; print(any([0,2,False])) #这个函数跟repr()函数一样,返回一个可打印的对象字符串方式表示。当遇到非ASCII码时 #就会输出\x,\u或\U等字符来表示。与Python 2版本里的repr()是等效的函数。 print(ascii("dsads"),ascii(66),ascii('b\23')) #将十进制转换为二进制; print(bin(10)) #返回布尔值,即True或False之一,如果参数为false或省略,则返回False; 否则返回True。 print(bool(1)) #根据传入的参数创建一个新的字节数组 #如果传入字符串必须给出编码 print(bytearray('你好','utf-8')) #当source参数是一个可迭代对象,那么这个对象中的元素必须符合大于0 小于256 print(bytearray([256,1,2])) #返回一个的“bytes”对象,返回bytes类型 bytes('中文','utf-8') #检查对象是否可以被调用 def func(): pass print(callable(func)) #返回整数所对应的Unicode字符,chr(97)返回字符串'a',而chr(8364)返回字符串'€'。 print(chr(126)) #是用来指定一个类的方法为类方法,类方法可以不实例化直接调用 class A: @classmethod def B(cls,arg1,): print(arg1) A.B(1) A().B(1) #将源编译为代码或者AST对象。代码对象能够通过exec语句来执行或者eval()进行求值。 #源可以是正常字符串,字节字符串或AST对象。 expr = "5+5-1" obj = compile(expr,"","eval") print(eval(obj)) #返回值为real + imag * j的复数或者转化一个字符串或数为复数。如果第一个参数为字符串,则不需要指定第二个参数。 print(complex(1, 2)) print(complex(1)) print(complex("1+2j")) # 参数是一个对象和一个字符串。 该字符串必须是对象属性之一的名称。 class A: def a1(self): print("a1") def a2(self): print("a2") obj = A print(dir(obj)) delattr(obj, "a1") print(dir(obj)) #dir 返回对象中的方法 strs="aaa" print(dir(strs)) #返回两个数值的商和余数 print(divmod(7,3)) #用于遍历序列中的元素以及它们的下标 print(enumerate([1,2,3]))#返回的是可迭代的对象 for i,j in enumerate(('A','B','C')): print(i,j) #将字符串str当成有效的表达式来求值并返回计算结果。 print(eval("1+2+3")) print(eval("False or True")) #字符串str当成动态语句块执行并返回结果 exec('a=1+2+3') print(a) #使用指定方法(方法,函数),过滤可迭代对象的元素 def add(arg): return arg > 3 for i in filter(add,[1,2,3,4,5]): print(i) #浮点型 print(float(11)) #格式化显示 更多方法请参考官方说明 print('{:,.2f}'.format(111111)) #根据传入的参数创建一个新的不可变集合 a = frozenset([1,2,3,4,5]) print(a) #获取对象的属性值 class A(): def __init__(self,): self.name = "123" b = A() print(getattr(b,'name')) #返回当前作用域内的全局变量和其值组成的字典 print(globals()) #检查对象是否含有属性 class A(): def __init__(self,): self.name = "123" b = A() print(hasattr(b,'name')) #哈希值计算 #在当前环境中是唯一的 print(hash('Hello')) #help帮助 def funcs(args): """ Function description :param args: args = list :return: """ pass print(help(funcs)) #转换16进制 print(hex(44)) #显示对象的标识符 print(id("123")) #input标准输入 s = input("user name:") print(s) #int返回整数 print(int(1.2)) print(int("2")) #判断对象是否是类或者类型元组中任意类元素的实例 print(isinstance("1",int)) print(isinstance(1.1,(int,float))) #判断类是否是另外一个类或者类型元组中任意类元素的子类 print(dir(str)) print(issubclass(bytearray,str)) print(issubclass(bool,int)) #根据传入的参数创建一个新的可迭代对象 a = iter('12345') print(next(a)) print(next(a)) #返回对象的长度len a = [1,2,3,4] #转换列表 print(list("abcd")) #返回当前作用域内的局部变量和其值组成的字典 def A(): print(locals()) s = 1 print(locals()) A() #使用指定方法去作用传入的每个可迭代对象的元素,生成新的可迭代对象 def add(x): return x+100 lists = [1,2,3,4] for i in map(add,lists): print(i) #max:返回最大值 print(max(1,2,3)) print(max([1,2,3,4])) #在进行切片并赋值数据时,不需要重新copy原列表数据,可以直接映射原数据内存; s = memoryview(b'abcd') print(s[1]) #返回最小值 print(min(1,2,3)) print(min([2,3])) #返回可迭代对象中的下一个元素值 a = iter('1234') print(next(a)) #创建一个新的object对象(新式类) class B(object): pass #转化成8进制数字符串 print(oct(10)) #open文件操作 file = open('test.txt',encoding="utf-8") #ord:返回Unicode字符对应的整数 print(ord("A")) #幂运算 print(pow(2,3)) #标准输出 print() #property:标示属性的装饰器 #类中使用具体方法请百度,或者等待后续更新 property #range:根据传入的参数创建一个新的range对象 range(10) range(1,10) """repr()函数得到的字符串通常可以用来重新获得该对象,repr()的输入对python比较友好。 通常情况下obj==eval(repr(obj))这个等式是成立的。""" obj='Python' print(eval(repr(obj))) #翻转序列 a = reversed([1,2,3,4,5]) print(list(a)) #round:对浮点数进行四舍五入求值 print(round(1.5)) #set 转换成集合 print(set([1,2,3])) #setattr:设置对象的属性值 class A(): def __init__(self,age): self.age = age s = A(11) print(s.age) setattr(s,'age',22) print(s.age) #根据传入的参数创建一个新的切片对象 c1 = slice(3) c2 = slice(2,4) c3 = slice(0,5,2) s = [1,2,3,4,5,6] print(s[c1]) print(s[c2]) print(s[c3]) #排序,返回一个新的列表默认按字符ascii码排序 a = [4,3,2,1,7] print(sorted(a)) #标示方法为静态方法的装饰器 class B(object): def __init__(self,age): self.age = age @staticmethod def hello(args): print(args) B.hello("Hello World") #字符串类型 print(str(123)) #求和 print(sum([1,2,3,4])) #根据传入的参数创建一个新的子类和父类关系的代理对象 class A(object): def __init__(self): print("我是 A Clase") class B(A): def __init__(self): print("我是 B Class") super().__init__() b = B() #元祖 tuple([1,2,3,4]) #type 返回对象的类型 print(type([1])) print(type("1")) #返回当前作用域内的局部变量和其值组成的字典,或者返回对象的属性列表 def func(): print(vars()) s = 1 print(vars()) func() #聚合传入的每个迭代器中相同位置的元素,返回一个新的元组类型迭代器 list1 = [1,2,3] list2 = ["A","B","C","D"] print(zip(list1,list2)) for i in zip(list1,list2): print(i) #__import__:动态导入模块 __import__
更多简学Python第三章__函数式编程、递归、内置函数 相关文章请关注PHP中文网!