函数是什么
函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的。程序里函数的定义是:
定义:将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可
特性:
- 减少重复代码
- 使程序变的可扩展
- 使程序变得易维护
实例1
def calcu(x,y):
res = x**y
return res #返回执行结果
result = calc(2,2)
print(result )
实例2
def student_fun(name,age,post): print("----学生信息------") print("姓名:",name) print("年龄:",age) print("职业:",post) print(‘‘) student_fun(‘邹俊安‘,17,‘学生‘) student_fun(age=17,name=‘文艺‘,post=‘学生‘) student_fun(‘王秋杰‘,45,‘老师‘)
函数的参数
形参:变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量
实参:可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值
name = "邹俊安" def change_name(name): print("修改前:", name) name = "罗奥" print("修改后", name) change_name(name) print("name是什么?", name) #输出的name还是邹俊安
函数的作用域
函数内一般情况无法修改函数外变量
name = "邹君安" def change_name(): name = "罗奥" change_name(name) print("name是什么?", name) #name还是邹俊安
可以通过global关键字来访问外部变量
name = "邹君安" def change_name(): global name name = "罗奥" change_name(name) print("name是什么?", name) #name还是邹俊安
函数递归
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
注意:
1. 必须有一个明确的结束条件。
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少。
3. 递归效率不高,递归层次过多会导致栈溢出。(经过测试python3.6的最大的递归此时为978次)
def calc(n): print(n) if int(n/2) ==0: return n return calc(int(n/2)) calc(10) """ 输出: 10 5 2 1 """
匿名函数
匿名函数就是不需要显式的指定函数
def calc1(n): return n ** 2 calc2 = lambda n: n ** 2 #结果相同 print(calc1(10)) print(calc2(10))
高阶函数
一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
def f(n): return n*2 def add(a,b,f): return f(a) + f(b) result = add(1,2,f) print(result) #结果:6
装饰器
需要知识
1.函数即变量
2.高阶函数
a.把函数名当实参传给另外一个函数
b.返回值包含函数名
3.嵌套函数
高阶函数+嵌套函数=》装饰器
*装饰器*
定义:本质是函数,(装饰其他函数)就是为其他函数添加功能
原则:a.不能修改被装饰的函数源代码
b.不能修改被装饰的函数调用方式
模型:
def 函数名1(装饰器参数): def 函数名2(被装饰函数名): def 函数名3(被装饰函数的参数) 。。使用装饰器参数。。 返回值 = 被装饰函数使用(传递被装饰函数的参数) 。。balabala。。 return 返回值 return 函数名3 return 函数名2 @函数名1(装饰器参数) def 装饰函数(参数): 。。balabala。。
现在你新入职了一家公司,工作是维护更新本公司网站,公司网站有3个入口: index、manage、topic,现在公司要求要在manage和topic入口需要登陆验证,函数代码极其复杂,而且很多地方都有调用,这时装饰器就派上了用处。
实例:
username,password = ‘09w09‘,‘12345‘ def check_user(check_type): def decorator(func): def func_num(*arg1,**arg2): if check_type == True: usernm = input("Please input username:") passwd = input("Please input username:") if usernm == username and passwd == password: res = func(*arg1,**arg2) print(‘执行函数后继续执行‘.center(50,‘-‘)) return res else: exit(0) else: passwd = input("09w09 please input password:") if passwd == password: res = func(*arg1, **arg2) print(‘执行函数后继续执行‘.center(50, ‘-‘)) return res else: exit(0) return func_num return decorator def index(): print(‘Welcome to 09w09\‘s index‘.ljust(50,‘*‘)) @check_user(True) def manage(x): print(‘this is manage page!‘.ljust(50,‘*‘),x) @check_user(False) def topic(): print(‘this is topic page‘.ljust(50,‘*‘)) return ‘\nok!\n‘ index() manage(‘09w09‘) print(topic())
迭代器
迭代是Python最强大的功能之一,是访问集合元素的一种方式。
迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件
实例:
>>> a = iter([1,2,3,4,5]) >>> a <list_iterator object at 0x00000238F2D6DE48> >>> a.__next__() 1 >>> a.__next__() 2 >>> next(a) 3 >>> next(a) 4 >>> next(a) 5 >>> next(a) Traceback (most recent call last): File "<pyshell#7>", line 1, in <module> next(a) StopIteration
生成器
在 Python 中,使用了 yield 的函数被称为生成器(generator)。
跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行
实例1:
#生成器变成list print([i*2 for i in range(10)]) #list变成生成器 print(iter([1,2,3,4,10,6,7,8]))
实例2:
def produce(x): str = ‘*‘ for i in range(x): yield str str+=‘*‘ def print_(p): while True: try: print(next(p)) except StopIteration : print(‘ok:‘) break print_(produce(10)) """ 输出结果: * ** *** **** ***** ****** ******* ******** ********* ********** ok! """
yield实现在单线程的情况下实现并发运算的效果
import time def consumer(name): print(‘%s同学准备吃包子了‘ % name) while True: baozi = yield #每次执行都会停留在这里, print("%s同学吃了%s馅包子" % (name,baozi)) def producer(filling): c1 = consumer(‘陈敏‘) c2 = consumer(‘马国正‘) c1.__next__() c2.__next__() print(‘王嘉宁开始做包子了!‘) for i in range(10): time.sleep(1) print(‘陈敏做了2个%s馅包子‘ % filling) c1.send(filling) c2.send(filling) producer(‘韭菜‘)