码迷,mamicode.com
首页 > 其他好文 > 详细

4 - 函数&装饰器 and 迭代器&生成器

时间:2018-02-11 21:23:30      阅读:145      评论:0      收藏:0      [点我收藏+]

标签:alc   student   div   老师   font   特点   call   很多   不同的   

函数是什么

函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的。程序里函数的定义是:

定义:将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可

特性

  1. 减少重复代码
  2. 使程序变的可扩展
  3. 使程序变得易维护

实例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(韭菜)

 

 

4 - 函数&装饰器 and 迭代器&生成器

标签:alc   student   div   老师   font   特点   call   很多   不同的   

原文地址:https://www.cnblogs.com/StringSir/p/8443015.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!