问:常见的服务器有哪些?
答:Tomcat, Jboss, websphere, weblogic(IBM) …
递归函数
递归就是子程序(或函数)直接调用自己或通过一系列调用语句间接调用自己,是一种描述问题和解决问题的基本方法.(一句话,自己调用自己)
def digui(a):
sum=a#一个变量'接收结果'
for i in range(1,a):#计算直到n的阶乘
sum*=i
return sum#循环完之后,返回值
print(digui(10))
递归的核心其实就是利用函数自己定义的变量/常量,再去通过函数自己去调用自己的值
def fn():
fn()
#无穷递归函数:会将数据溢出,泄露核心数据,在实际的工作研发过程中不能使用
# 练习
# 创建一个函数,用来检查一个任意的字符串是否是回文字符串,如果是返回True,否则返回False
# 回文字符串,字符串从前往后念和从后往前念是一样的
# abcba
# abcdefgfedcba
# 先检查第一个字符和最后一个字符是否一致,如果不一致则不是回文字符串
# 如果一致,则看剩余的部分是否是回文字符串
# 检查 abcdefgfedcba 是不是回文
# 检查 bcdefgfedcb 是不是回文
# 检查 cdefgfedc 是不是回文
# 检查 defgfed 是不是回文
# 检查 efgfe 是不是回文
# 检查 fgf 是不是回文
# 检查 g 是不是回文
def hui_wen(s):
'''
该函数用来检查指定的字符串是否回文字符串,如果是返回True,否则返回False
参数:
s:就是要检查的字符串
'''
# 基线条件
if len(s) < 2 :
# 字符串的长度小于2,则字符串一定是回文
return True
elif s[0] != s[-1]:
# 第一个字符和最后一个字符不相等,不是回文字符串
return False
# 递归条件
return hui_wen(s[1:-1])
# def hui_wen(s):
# '''
# 该函数用来检查指定的字符串是否回文字符串,如果是返回True,否则返回False
# 参数: s:就是要检查的字符串
# '''
# # 基线条件
# if len(s) < 2 :
# # 字符串的长度小于2,则字符串一定是回文
# return True
# # 递归条件
# return s[0] == s[-1] and hui_wen(s[1:-1])
print(hui_wen('abcdefgfedcba'))
- 递归的思想:
- 基线条件:问题可以被分解为的最小问题,当满足基线条件时,递归就不在执行了
- 递归条件:将问题继续分解的条件
def factorial(n):
#该函数用来求任意数的阶乘
#参数:n 要求阶乘的数字
# 基线条件 判断n是否为1,如果为1则此时不能再继续递归
if n == 1 :
# 1的阶乘就是1,直接返回1
return 1
# 递归条件
return n * factorial(n-1)
# print(factorial(10))
高阶函数
- 在Python中,函数是一等对象
-
一等对象一般都会具有如下特点:
① 对象是在运行时创建的
② 能赋值给变量或作为数据结构中的元素
③ 能作为参数传递
④ 能作为返回值返回 -
高阶函数
- 高阶函数至少要符合以下两个特点中的一个
① 接收一个或多个函数作为参数
② 将函数作为返回值返回
- 高阶函数至少要符合以下两个特点中的一个
-
l=[1,2,3,4,5,6,7,8,9,10]
def fn(lst):
#创建一个新列表,将获取的偶数放到列表当中
new_list=[]
for n in l:
if(n%2==0):
new_list.append(n)
return new_list
print(fn(l))#将l列表的元素放到函数里面去调用
-
总结:
- 高阶函数在实际有工作中大量使用,作为函数返回
- 利用高阶函数可以减少代码块的重用,避免大量的循环判断语句的出现
- 利用高阶函数让业务代码快件显得更加清晰
-
常用高阶函数
题目 :这个函数用来检查指定的数字是否大于5
def fn3(i):
if i > 5 :
return True
return False
def fn(func , lst) :
'''
fn()函数可以将指定列表中的所有偶数获取出来,并保存到一个新列表中返回
参数:
lst:要进行筛选的列表
'''
# 创建一个新列表
new_list = []
# 对列表进行筛选
for n in lst :
# 判断n的奇偶
if func(n) :
new_list.append(n)
# if n > 5 :
# new_list.append(n)
# 返回新列表
return new_list
# def fn4(i):
# if i % 3 == 0:
# return True
# return False
def fn4(i):
return i % 3 == 0
# print(fn(fn4 , l))
# filter()
# filter()可以从序列中过滤出符合条件的元素,保存到一个新的序列中
# 参数:
# 1.函数,根据该函数来过滤序列(可迭代的结构)
# 2.需要过滤的序列(可迭代的结构)
# 返回值:
# 过滤后的新序列(可迭代的结构)
# fn4是作为参数传递进filter()函数中
# 而fn4实际上只有一个作用,就是作为filter()的参数
# filter()调用完毕以后,fn4就已经没用
# 匿名函数 lambda 函数表达式 (语法糖)
# lambda函数表达式专门用来创建一些简单的函数,他是函数创建的又一种方式
# 语法:lambda 参数列表 : 返回值
# 匿名函数一般都是作为参数使用,其他地方一般不会使用
def fn5(a , b):
return a + b
# (lambda a,b : a + b)(10,20)
# 也可以将匿名函数赋值给一个变量,一般不会这么做
fn6 = lambda a,b : a + b
# print(fn6(10,30))
r = filter(lambda i : i > 5 , l)
# print(list(r))
# map()
# map()函数可以对可跌倒对象中的所有元素做指定的操作,然后将其添加到一个新的对象中返回
l = [1,2,3,4,5,6,7,8,9,10]
r = map(lambda i : i ** 2 , l)
# print(list(r))
# sort()
# 该方法用来对列表中的元素进行排序
# sort()方法默认是直接比较列表中的元素的大小
# 在sort()可以接收一个关键字参数 , key
# key需要一个函数作为参数,当设置了函数作为参数
# 每次都会以列表中的一个元素作为参数来调用函数,并且使用函数的返回值来比较元素的大小
l = ['bb','aaaa','c','ddddddddd','fff']
# l.sort(key=len)
l = [2,5,'1',3,'6','4']
l.sort(key=int)
# print(l)
# sorted()
# 这个函数和sort()的用法基本一致,但是sorted()可以对任意的序列进行排序
# 并且使用sorted()排序不会影响原来的对象,而是返回一个新对象
l = [2,5,'1',3,'6','4']
# l = "123765816742634781"
print('排序前:',l)
print(sorted(l,key=int))
print('排序后:',l)
常用内置函数
num=-1
print(abs(num))#绝对值
#sorted(list)排序--reverse-True(表示排序-倒序)
print(sorted([1,23,34,45,56,14,51,59],reverse=True))
print(sorted([1,23,34,45,56,14,51,59]))
#reverse-True 这个直接操作数据,如果出现一个False,是是按照假命题判断条件,一般直接写True
#sorted原理就是克隆机制,不会影响原数据----在工作中遍历测试数据
l=['2',5,'7',8,'9',3,'4',3]
l.sort(key=int)
#sort方法的key可以传递任意数据类型的参数
#l.sort(key=int str)
print(l)
print(sum([100,200]))
#函数的优势:可以直接获取值
print(round(12.12345,2))
#对应数据库
num=1
print(isinstance(num,int))
#python是强类型语言,在定义变量和常量等不需要制定特定的类型解释器可以判断类型,但是慢
exec()
#execute()表示的是预编译--针对于所有计算机语言都有效
匿名函数
匿名函数:定义函数的过程中,没有给定名称的函数就叫做匿名函数;Python中使用lambda表达式来创建匿名函数。
lambda 来创建匿名函数规则。
●lambda只是一个表达式,函数体比def简单很多。
●lambda的主体是一个表达式,而不是一个代码块,所以不能写太多的逻辑进去。
●lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。
●lambda定义的函数的返回值就是表达式的返回值,不需要return语句块
●lambda表达式的主要应用场景就是赋值给变量、作为参数传入其它函数
lambda匿名函数的表达式规则是:lambda 参数列表: 表达式
print((lambda a,b:a+b)(10,20))
#没有调用函数名称
#没有返回值
lambda表达式就是一种不写函数名称的表达式,经常使用
fn(1,3)通过函数赋值的缺陷:对Python解释器解释代码不利,维护代码困难
#将一个常量变为一个函数,不建议使用
fn6=(lambda a,b:a+b)
print(fn6(2,3))#此处的fn6是一个函数
问: 为什么不建议使用?
答: 变量和常量等属于优先级较低(精度要求),转化为函数----精度较高
结果:精度损失,
mysql(auto increment) 和 Oracle(序列)的主键递增是什么?
闭包
-将函数作为返回值返回,也是一种高阶函数
-这种高阶函数我们也称为叫做闭包,通过闭包可以创建一些只有当前函数能访问的变量,可以将一些私有的数据藏到的闭包中
-变量其实就是一个变量,通过函数赋值以后,变量自身就是一个函数,这个函数不会被其他函数进行调用访问
def fn():#外部函数
a = 10
# 函数内部再定义一个函数
def inner():#内部函数
print('我是fn2' , a)
# 将内部函数 inner作为返回值返回
return inner
r=fn()
#r是一个函数,是调用fn()后返回的函数
#这个函数实在fn()内部定义,并不是全局函数
#所以这个函数总是能访问到fn()函数内的变量
- 形成闭包的要件
① 函数嵌套
② 将内部函数作为返回值返回
③ 内部函数必须要使用到外部函数的变量
def make_averager():
# 创建一个列表,用来保存数值
nums = []
# 创建一个函数,用来计算平均值
def averager(n) :
# 将n添加到列表中
nums.append(n)
# 求平均值
return sum(nums)/len(nums)
return averager
averager = make_averager()
print(averager(10))#给变量通过函数调用机制赋值
print(averager(20))
print(averager(30))
print(averager(40))
装饰器
希望函数可以在计算前,打印开始计算,计算结束后打印计算完毕
我们可以直接通过修改函数中的代码来完成这个需求,但是会产生以下一些问题
① 如果要修改的函数过多,修改起来会比较麻烦
② 并且不方便后期的维护
③ 并且这样做会违反开闭原则(OCP)----保证数据的同步性
程序的设计,要求开发对程序的扩展,要关闭对程序的修改
def fn1():
print('我是fn函数....')
def fn2():
print('开始执行')
fn1()
fn2()#遵守开闭原则(开是访问法不函数,闭是调用内部函数返回结果)
其实 高阶函数 和 递归 和 装饰器 的核心是:通过一个变量,让函数指挥变量去直接访问调用机制
其实装饰器也是一种很好的设计模式
def begin_end(old):
'''
用来对其他函数进行扩展,使其他函数可以在执行前打印开始执行,执行后打印执行结束
参数:old 要扩展的函数对象
'''
# 创建一个新函数
def new_function(*args , **kwargs):
print('开始执行~~~~')
# 调用被扩展的函数
result = old(*args , **kwargs)
print('执行结束~~~~')
# 返回函数的执行结果
return result
# 返回新函数
return new_function
#开: 定义函数的操作过程
#闭: 调用函数,返回结果
f = begin_end(fn)
f2 = begin_end(add)
f3 = begin_end(mul)
# r = f()
# r = f2(123,456)
# r = f3(123,456)
# print(r)
# 像begin_end()这种函数我们就称它为装饰器
# 通过装饰器,可以在不修改原来函数的情况下来对函数进行扩展
# 在开发中,我们都是通过装饰器来扩展函数的功能的
# 在定义函数时,可以通过@装饰器,来使用指定的装饰器,来装饰当前的函数
# 可以同时为一个函数指定多个装饰器,这样函数将会安装从内向外的顺序被装饰
写代码的技巧:
按照流程–面向对象的流程:
1.定义函数 -->2.写内部函数–>3.将外部值返回–>4.定义变量赋值给外部函数–>5.通过内部函数将值打印输出