函数

函数的基本使用

 

1、什么是函数?   

在程序中,函数就具备某一功能的工具

事先将工具准备好即函数的定义

遇到应用场景拿来就用即函数的调用

所以务必记住:#函数的使用必须遵循先定义,后调用的原则

 

2、为何要用函数

 不用函数问题是:

 1、程序冗长

 2 程序的扩展性差

 3 程序的可读性差

 

3 如何用函数:

  函数的使用必须遵循先定义,后调用的原则

 

 def 函数名(参数1,参数2,...):

 

     函数功能的描述信息

     :param 参数1: 描述

     :param 参数2: 描述

     :return: 返回值

     '''

     代码1

     代码2

     代码3

     ...

     return 返回值

 

函数的分类

1、内置函数
为了方便我们的开发,针对一些简单的功能,python解释器已经为我们定义好了的函数即内置函数。对于内置函数,我们可以拿来就用而无需事先定义,如len(),sum(),max()
ps:我们将会在最后详细介绍常用的内置函数。

2、自定义函数
很明显内置函数所能提供的功能是有限的,这就需要我们自己根据需求,事先定制好我们自己的函数来实现某种功能,以后,在遇到应用场景时,调用自定义的函数即可。



什么时候该有返回值?
    调用函数,经过一系列的操作,最后要拿到一个明确的结果,则必须要有返回值
    通常有参函数需要有返回值,输入参数,经过计算,得到一个最终的结果

什么时候不需要有返回值?     调用函数,仅仅只是执行一系列的操作,最后不需要得到什么结果,则无需有返回值     通常无参函数不需要有返回值

 

 

 准备好工具=>函数的定义阶段

def register():

    while True:

        uname=input('username>>:').strip()

        if uname.isalpha():

            break

        else:

            print('用户名必须由字母组成傻叉')

 

    while True:

        pwd1=input('密码>>: ').strip()

        pwd2=input('重复输入密码>>: ').strip()

        if pwd1 == pwd2:

            break

        else:

            print('两次输入的密码不一致,眼瞎吗')

 

    with open('db.txt','at',encoding='utf-8') as f:

        f.write('%s:%s\n' %(uname,pwd1))

        f.flush()

 

def auth():

    #认证功能

    inp_uname=input('请输入你的账号:').strip()

    inp_pwd=input('请输入你的密码:').strip()

    with open('db.txt','rt',encoding='utf-8') as f:

        for line in f:

            info=line.strip('\n').split(':')

            if inp_uname == info[0] and inp_pwd == info[1]:

                print('login successfull')

                break

        else:

            print('账号或密码错误')

 

 拿来就用=>函数的调用阶段

 print(register)

 register()

 auth()

 register()

 register()

 register()

 

函数的定义阶段和调用阶段

 

 函数的使用必须遵循先定义,后调用的原则,

 没有事先定义函数,而直接引用函数名,就相当于在引用一个不存在的变量名

 

1、函数定义阶段:只检测函数体的语法,不执行函数体代码

 def func():

     print('1111')

     print('222')

     print('333')

 

2、函数调用阶段:执行函数体代码

 func()

 

 例1

 def foo():

     print('from foo')

     bar()

 

 foo()

 

 例2

 def bar():

     print('from bar')

 

 def foo():

     print('from foo')

     bar()

 

 foo()

 

 例3

 def foo():

     print('from foo')

     bar()

 

 def bar():

     print('from bar')

 

 foo()

 

 

 例4

 def foo():

     print('from foo')

     bar()

 

 foo()

 

 def bar():

     print('from bar')

 

函数的定义

 

 

定义函数时的参数就是函数体接收外部传值的一种媒介,其实就一个变量名

 

1、无参函数:

 在函数定义阶段括号内没有参数,称为无参函数

 注意:定义时无参,意味着调用时也无需传入参数

 应用:

如果函数体代码逻辑不需要依赖外部传入的值,必须定义无参函数

 

 def func():

     print('hello world')

 func()

 

 

2、有参函数

 在函数定义阶段括号内有参数,称为有参函数

 注意:定义时有参,意味着调用时也必须传入参数

 应用:

如果函数体代码逻辑需要依赖外部传入的值,必须定义成有参函数

 def sum2(x,y):

     # x=10

     # y=20

     res=x+y

     print(res)

 

 sum2(10,20)

 sum2(30,40)

 

def check_user():

    while True:

        uname=input('username>>:').strip()

        if uname.isalpha():

            return uname

            # break

        else:

            print('用户名必须由字母组成傻叉')

 

def check_pwd():

    while True:

        pwd1=input('密码>>: ').strip()

        pwd2=input('重复输入密码>>: ').strip()

        if pwd1 == pwd2:

            return pwd1

        else:

            print('两次输入的密码不一致,眼瞎吗')

 

def db_hanle(uname,pwd1):

    with open('db.txt','at',encoding='utf-8') as f:

        f.write('%s:%s\n' %(uname,pwd1))

        f.flush()

 

def register():

    # 检测用户名是否合法

    x=check_user() #x='EGON'

    # 检测密码是否合法

    y=check_pwd() #y='123'

 

    # 写入数据文件

    # db_hanle(合法的用户名,合法的密码)

    db_hanle(x,y)

 

 

 register()

 

 

 

3、空函数

 

 def func():

     pass

 

 

def check_user():

    pass

 

def check_pwd():

    pass

 

def write_db(x,y):

    pass

 

def register():

    #1 输入用户名,并进行合法性校验

    #2 输入密码,并进行合法性校验

    #3 将合法的用户名、密码写入文件

    x=check_user()

    y=check_pwd()

    write_db(x,y)

 

'函数的返回值

1、什么是返回值

    返回值是一个函数的处理结果,

 

2、为什么要有返回值

    如果我们需要在程序中拿到函数的处理结果做进一步的处理,则需要函数必须有返回值

 

 

3、函数的返回值的应用

    函数的返回值用return去定义

    格式为:

        return 值

 

    注意:

        1、return是一个函数结束的标志,函数内可以有多个return,

            但只要执行一次,整个函数就会结束运行

 

        2、return 的返回值无类型限制,即可以是任意数据类型

        3、return 的返回值无个数限制,即可以用逗号分隔开多个任意类型的值

            0个:返回None,ps:不写return默认会在函数的最后一行添加return None

            1个:返回的值就是该值本身

            多个:返回值是元组

'''

 

# def max2(x,y): #x=3000,y=2000

#     if x > y:

#         return x #return 3000

#     else:

#         return y #reuturn 2000

#

# res=max2(3000,2000)

#

# annual_salary=res * 12

#

# print(annual_salary)

 

 

 

 

# def foo():

#     print(1)

#     print(2)

#     print(3)

#     return [1,2,3],'a',('a','b'),{1,2}

#     print(4)

#     print(5)

#     print(6)

#

# res=foo()

# print(res)

 

 

# def bar():

#     print(1)

#     print(1)

#     print(1)

#     print(1)

#     return

#     print(2)

#     print(3)

#     print(4)

#

# res=bar()

# print(res)

 

 

函数的调用

1 什么是调用函数

    函数名(...)即调用函数,会执行函数体代码,直到碰到return结束或者一直运行完毕所有代码

 

2 为何要调用函数

    用函数的功能

 

3、函数调用分为三种形式

    max2(1,2)

    res=max2(3000,2000) * 12

    res=max2(max2(1000,2000),3000)

'''

 

# def foo():

#     print(1)

#     print(2)

#     print(3)

#     return None

# res=foo()

# print(res)

 

 

def max2(x,y):

    if x > y:

        return x

    else:

        return y

 

#形式一:

# max2(1,2)

 

#形式二:

# res=max2(3000,2000) * 12

# print(res)

 

#形式三:

res=max2(max2(1000,2000),3000)

print(res)

 

函数的参数

#总的分类:

# #1、形参:在函数定义阶段括号内定义的参数,称之为形式参数,简称形参,本质就是变量名

# def foo(x,y): #x=1,y=2

#     print(x)

#     print(y)

# #2、实参:在函数调用阶段括号内传入的值,称之为实际参数,简称实参,本质就是变量的值

# foo(1,2)

#

 

#详细的分类:

#一、位置参数:

#位置形参:在函数定义阶段,按照从左到右的顺序依次定义的形参,称之为位置形参

#特点:但凡是按照位置定义的形参,都必须被传值,多一个不行,少一个也不行

# def foo(x,y):

#     print('x:',x)

#     print('y:',y)

 

#位置实参:在函数调用阶段,按照从左到右的顺序依次定义的实参,称之为位置实参

#特点:按照位置为对应的形参依次传值

# foo(1,2)

# foo(2,1)

 

 

#二、关键字实参:在调用函数时,按照key=value的形式为指定的参数传值,称为关键字实参

#特点:可以打破位置的限制,但仍能为指定的形参赋值

# foo(y=2,x=1)

 

#注意:

#1、可以混用位置实参与关键字实参,但位置实参必须放在关键字实参的前面

# foo(1,y=2)

# foo(y=2,1) #SyntaxError: positional argument follows keyword argument

 

#2、可以混用,但不能对一个形参重复赋值

# foo(1,y=2,x=10)

 

 

#三:默认参数:在函数定义阶段,就已经为形参赋值,该形参称为默认形参

#特点:在定义阶段就已经被赋值,意味着在调用可以不用为其赋值

# def foo(x,y=10):

#     print('x:',x)

#     print('y:',y)

 

# foo(1)

# foo(1,3)

# 注意:

#1、位置形参必须放到默认形参的前面,否则报语法错误

# def foo(x=1,y):

#     pass

 

#2、默认参数的值只在定义阶段赋值一次,即默认参数的值在函数定义阶段就已经固定死了

 

# m=10

# def foo(x=m,y=11):

#     print(x)

#     print(y)

# m=1111111111111111111111111111111111111111111111111111111111

# foo()

 

#3、默认参数的值通常应该定义不可变类型

 

# def register(name,hobby,hobbies=[]):

#     hobbies.append(hobby)

#     print('%s的爱好' %name,end=':')

#     print(hobbies)

#

# register('egon','play')

# register('alex','piao')

# register('lxx','烫头')

 

# def register(name,hobby,hobbies=None):

#     if hobbies is None:

#         hobbies=[]

#     hobbies.append(hobby)

#     print('%s的爱好' %name,end=':')

#     print(hobbies)

#

# register('egon','play')

# register('alex','piao')

# register('lxx','烫头')

 

 

 

#总结:

#实参的应用:取决于个人习惯,

#形参的应用:

#1、位置形参:大多数情况下的调用值都不一样,就应该将该参数定义成位置形参

#2、默认形参:大多数情况下的调用值都一样,就应该将该参数定义成默认形参

# def register(name,age,sex='male'):

#     print(name)

#     print(age)

#     print(sex)

#

#

# register('egon',18,)

# register('大脑门',73,'female')

# register('小脑门',84,)

# register('大高个',18,)

 

 

 

#四:可变长参数:指的是在调用函数时,传入的参数个数可以不固定

#而调用函数时,传值的方式无非两种,一种位置实参,另一种时关键字实参

#所以对应着,形参也必须有两种解决方案,来分别接收溢出的位置实参(*)与关键字实参(**)

 

#1、形参中某个参数带*

#形参中的*会将溢出的位置实参全部接收,然后存储元组的形式,然后把元组赋值给*后的变量名

# def foo(x,y,*z): #x=1,y=2,z=(3,4,5,6,7)

#     print(x)

#     print(y)

#     print(z)

# foo(1,2,3,4,5,6,7)

 

# 应用

# def my_sum(*nums):

#     res=0

#     for num in nums:

#         res+=num

#     return res

#

# print(my_sum(1,2,3,4,5))

 

# 2、实参中的参数也可以带*

# 实参中带*,*会将该参数的值循环取出,打散成位置实参

#ps:以后但凡碰到实参中带*的,它就是位置实参,应该立马打散成位置实参去看

# def foo(x,y,z):

#     print(x,y,z)

 

# foo(1,*[2,3]) #foo(1,2,3)

# foo(1,*'he') #foo(1,'h','e')

# foo(1,*(2,3,4)) #foo(1,2,3,4)

 

# def foo(x,y,z,*args):

#     print(x)

#     print(y)

#     print(z)

#     print(args)

#

# foo(1,2,3,4,5,6,7,*[8,9,10,11]) #foo(1,2,3,4,5,6,7,8,9,10,11)

#注意:约定俗成形参中的*变量名的写法都是:*args

 

 

 

#1、形参中某个参数带**

#形参中的**会将溢出的关键字实参全部接收,然后存储字典的形式,然后把字典赋值给**后的变量名

# def foo(x,y,**z): #x=1,y=2,z={'c':5,'b':4,'a':3}

#     print(x)

#     print(y)

#     print(z)

# foo(1,2,a=3,b=4,c=5)

 

# 2、实参中的参数也可以带**,该参数必须是字典

# 实参中带**,**会将该参数的值循环取出,打散成关键字实参

#ps:以后但凡碰到实参中带**的,它就是关键字实参,应该立马打散成关键字实参去看

# def foo(x,y,z):

#     print(x)

#     print(y)

#     print(z)

 

# foo(1,2,**{'a':1,'b':2,'c':3,'z':3}) #foo(1,2,c=3,b=2,a=1,z=3)

# foo(**{'z':3,'x':1,'y':2}) #foo(y=2,x=1,z=3)

 

#注意:约定俗成形参中的**变量名的写法都是:**kwargs

 

# def index(name,age,sex):

#     print('welecome %s:%s:%s to index page' %(name,age,sex))

#

# def wrapper(*args,**kwargs): #args=(1,),kwargs={'x': 1, 'y': 2, 'z': 3}

#     index(*args,**kwargs) #index(*(1,),**{'x': 1, 'y': 2, 'z': 3}) #index(1,x=1,y=2,z=3)

#

# wrapper(name='egon',sex='male',age=18)

#

 

#五 命名关键字形参:在函数定义阶段,*后面的参数都是命名关键字参数(**)

# 特点:在传值时,必须按照key=value的传,并且key必须命名关键字参数指定的参数名

# def register(x,y,z,**kwargs): #kwargs={'b':18,'a':'egon'}

#     if 'name' not in kwargs or 'age' not in  kwargs:

#         print('用户名与年龄必须使用关键字的形式传值')

#         return

#     print(kwargs['name'])

#     print(kwargs['age'])

# register(1,2,3,a='egon',b=18)

 

 

# def register(x,y,z,*args,name='egon',age):

#     print(args)

#     print(name)

#     print(age)

# register(1,2,3,4,5,6,7,age=18)

#

 

 

 

# def foo(x,y=1,*args,z=1,a,b,**kwargs):

#     pass

 

 

# foo(1,*[1,2,3],a=1,**{'x':1,'y':2}) #foo(1,1,2,3,a=1,y=2,x=1)

 

 

# foo(1,2)

# foo(x=1,y=2)

 

 

open('a.txt','w',encoding='utf-8')

 

函数的对象

#函数是第一类对象的含义是函数可以被当作数据处理

 

 

 

def func(): #func=<function func at 0x0584BA50>

    print('from func')

 

# print(func)

 

 

x='hello'

#1、引用

# y=x

# f=func

# print(f)

# f()

 

 

#2、当作参数传给一个函数

# len(x)

# def foo(m):

#     # print(m)

#     m()

#

# foo(func)

 

 

#3、可以当作函数的返回值

# def foo(x): #x=func

#     return x #return func

#

# res=foo(func)

# print(res)

# res()

 

#4、可以当作容器类型的元素

# l=[x,]

 

# l=[func,]

# # print(l)

#

# l[0]()

 

 

 

def pay():

    print('支付。。。')

 

def withdraw():

    print('取款。。。')

 

def transfer():

    print('转账。。。')

 

def check_balance():

    print('查看余额。。。')

 

 

def shopping():

    print('购物。。。')

 

func_dic={

    '1':pay,

    '2':withdraw,

    '3':transfer,

    '4':check_balance,

    '6':shopping

}

 

while True:

    msg="""

    1 支付

    2 取款

    3 转账

    4 查看余额

    5 退出

    6 购物

    """

    print(msg)

    choice=input('>>: ').strip()

    if choice == '5':break

    if choice not in func_dic:

        print('输入的指令不存在傻叉')

        continue

    func_dic[choice]()

 

 

 函数嵌套

#函数的嵌套定义

def f1():

    def f2():

        print('from f2')

    f2()

f1()

 

 

 

 

# from math import pi

#

# def circle(radius,action='area'): #radius=10

#     def area():

#         return pi * (radius ** 2)

#

#     def perimeter():

#         return 2 * pi * radius

#

#     if action == 'area':

#         return area()

#     elif action == 'perimeter':

#         return perimeter()

#

# print(circle(10))

# print(circle(10,action='perimeter'))

 

 

 

 

 

#函数的嵌套调用

# def max2(x,y):

#     if x > y:

#         return x

#     else:

#         return y

#

# def max4(a,b,c,d):

#     res1=max2(a,b)

#     res2=max2(res1,c)

#     res3=max2(res2,d)

#     return res3

#

# print(max4(1,2,3,4))

 

 名称空间和作用域

 

 

 

1、名称空间namespaces

    存放名字与值绑定关系的地方

 

2、名称空间分为三大类

    内置名称空间:

        作用:存放python解释器自带的名字

        生命周期:

            在解释器启动时生效,在解释器关闭时失效

 

    全局名称空间:

        作用:除了内置的与局部的名字外,其余都是全局名字

        生命周期:

            在文件执行时生效,在文件执行完毕时失效

 

        例如:x,func,y,l,z都是

            x=1

            def func():

                a=1

 

            y=2

            l=[1,2]

 

            if 3 > 2:

                if

                    if

                        if

                            z=3

    局部名称空间:

        作用:用于存放函数调用期间函数体产生的名字

        生命周期:

            在文件执行过程

            如果调用了某个函数才会临时生效,在函数执行完毕后失效

 

    三种名称空间的加载顺序是:

        内置-》全局-》局部

 

    名称空间就是用来存放名字与值的绑定关系的,所以但凡要查找名字

    一定是从三者之一找到,查找顺序:

        从当前所在的位置倒着查找,如果当前所在的位置是局部名称空间,

        则查找顺序是:

            局部-》全局-》内置

 

3、作用域:

    域指的是区域、范围,作用域即作用的范围

 

    全局作用范围,全局作用域(内置名称空间与全局名称空间)

        全局有效,全局存活

    局部作用范围,局部作用域(局部名称空间)

        局部有效,临时存活

 

'''

 

# x=1

# # len=100

# def func():

#     y=2

#     len=1000

#     # print(len)

#     print(a)

# # func()

#

# print(len)

 

 

# def func():

#     y=2

#     print(x)

#

# x=1

# func()

#

# x=10

 

# x=1

# def f1():

#     def f2():

#         def f3():

#             zzz=333

#             print(x)

#         # x = 22222

#         f3()

#     # x=111111

#     f2()

#

# def bar():

#     print(x)

#

# f1()

# bar()

 

 

# 作用域关系是在函数定义阶段就固定死了,但凡调用函数都需要跑到定义阶段去找作用域关系

# x=1

# def f1():

#     print(x)

#

# # f1()

# x=1000000000000000000000000000000000000000000000000000000000000000

# def f2():

#     # print(f1)

#     x=11111111111111111111111111111

#     f1()

#

# f2()

 

 

 

#函数对象+作用域:******

# def f1():

#     x=1

#     def inner():

#         print('from inner',x)

#     return inner

#

# f=f1()

#

# # print(f)

#

# def bar():

#     x=111111111111111111111111111111111111111111111

#     f()

#

# bar()

 

 

#

# x=1

# def foo():

#     global x

#     x=2

#

# foo()

# print(x)

 

 

 

# x=1

# def f1():

#     def f2():

#         x=22222222

#         def f3():

#             global x

#             x=11111111111111111

#         f3()

#     f2()

#

# f1()

# print(x)

 

 

# x=1

# def f1():

#     # x=33333

#     def f2():

#         # x=22222222

#         def f3():

#             nonlocal x

#             x=20000000000

#         f3()

#         print(x)

#     f2()

#

# f1()

# print(x)

 

 

 

# 在局部如果想要修改全局的可变类型,不需要借助任何声明,可以直接修改

# 在局部如果想要修改全局的不可变类型,需要借助global声明,声明为全局的变量就可以直接修改了

 

# x=[]

# def f1():

#     x.append(1)

# f1()

# f1()

# print(x)

 

 

 闭包函数

#作用域关系在函数定义阶段时就已经固定死了,与调用位置无关

# 即:在任意位置调用函数都需要跑到定义函数时寻找作用域关系

 

# def f1():

#     x=1

#     def inner():

#         print(x)

#

#     return inner

#

# func=f1()

#

# def f2():

#     x=111111

#     func()

#

# f2()

 

# 闭包函数:

# 闭指的是:该函数是一个内部函数

# 包指的是:指的是该函数包含对外部作用域(非全局作用域)名字的引用

# def outter():

#     x = 1

#     def inner():

#         print(x)

#

#     return inner

#

# f=outter()

#

# def f2():

#     x=1111111

#     f()

#

# f2()

#

#

# def f3():

#     x=4444444444444

#     f()

#

# f3()

 

 

 

# 为函数体传值的方式一:使用参数的形式

# def inner(x):

#     print(x)

#

# inner(1)

# inner(1)

# inner(1)

# 为函数体传值的方式二:包给函数

'''

def outter(x):

    # x=1

    def inner():

        print(x)

    return inner

 

f=outter(1)

f()

'''

 

 

# import requests

#

# def get(url):

#     response=requests.get(url)

#     if response.status_code == 200:

#         print(response.text)

#

# get('https://www.baidu.com')

# get('https://www.baidu.com')

# get('https://www.baidu.com')

#

# get('https://www.python.org')

# get('https://www.python.org')

# get('https://www.python.org')

# get('https://www.python.org')

 

 

 

import requests

 

def outter(url):

    # url='https://www.baidu.com'

    def get():

        response=requests.get(url)

        if response.status_code == 200:

            print(response.text)

    return get

 

baidu=outter('https://www.baidu.com')

python=outter('https://www.python.org')

 

 

baidu()

baidu()

 

python()

python()

 

装饰器

'''

1、什么是装饰器

    器指的是工具,而程序中的函数就具备某一功能的工具

    装饰指的是为被装饰器对象添加额外功能

 

    就目前的知识来看:

        定义装饰器就是定义一个函数,只不过该函数的功能是用来为

        其他函数添加额外的功能

 

    其实:

        装饰器本身其实可以是任意可调用的对象

        被装饰的对象也可以是任意可调用的对象

 

 

2、为什么要用装饰器

    软件的维护应该遵循开放封闭原则

    开放封闭原则指的是:

        软件一旦上线运行后对修改源代码是封闭的,对扩展功能的是开放的

        这就用到了装饰器

 

    装饰器的实现必须遵循两大原则:

        1、不修改被装饰对象的源代码

        2、不修改被装饰对象的调用方式

    装饰器其实就在遵循1和2原则的前提下为被装饰对象添加新功能

 

3、如何用装饰器

'''

 

# import time

#

# def index():

#     start=time.time()

#     print('welcom to index')

#     time.sleep(3)

#     stop=time.time()

#     print('run time is %s' %(stop-start))

# index()

 

# import time

#

# def index():

#     print('welcom to index')

#     time.sleep(3)

#

# def f2():

#     print('from f2')

#     time.sleep(2)

#

# start=time.time()

# index()

# stop=time.time()

# print('run time is %s' %(stop-start))

#

# start=time.time()

# f2()

# stop=time.time()

# print('run time is %s' %(stop-start))

 

 

# import time

#

# def index():

#     print('welcom to index')

#     time.sleep(3)

#

# def timmer(func):

#     start=time.time()

#     func()

#     stop=time.time()

#     print('run time is %s' %(stop-start))

#

# timmer(index)

 

 

 

 

'''

import time

 

def index():

    print('welcom to index')

    time.sleep(3)

 

def timmer(func): #func=最原始的index

    # func=index

    def inner():

        start=time.time()

        func()

        stop=time.time()

        print('run time is %s' %(stop-start))

    return inner

 

# f=timmer(index)

# f()

 

# index=timmer(被装饰函数的内存地址)

index=timmer(index) #index=inner

 

index() #inner()

 

 

'''

import time

 

def index():

    print('welcom to index')

    time.sleep(3)

 

def timmer(func):

    #func=最原始的index

    def wrapper():

        start=time.time()

        func()

        stop=time.time()

        print('run time is %s' %(stop - start))

    return wrapper

 

index=timmer(index) #index=wrapper函数的内存地址

index()

 

 

 装饰器修正

无参装饰器

 # import time

#

# def index():

#     print('welcome to index')

#     time.sleep(3)

#     return 123

#

# def home(name):

#     print('welcome %s to home page' %name)

#     time.sleep(2)

#

#

# def timmer(func):

#     #func=最原始的index

#     def wrapper(*args,**kwargs):

#         start=time.time()

#         res=func(*args,**kwargs)

#         stop=time.time()

#         print('run time is %s' %(stop - start))

#         return res

#     return wrapper

#

#

# index=timmer(index)

# home=timmer(home)

#

# res=index()

# home('egon')

 

 

#装饰器语法糖

# 在被装饰对象正上方,并且是单独一行写上@装饰器名

 

# import time

# def timmer(func):

#     #func=最原始的index

#     def wrapper(*args,**kwargs):

#         start=time.time()

#         res=func(*args,**kwargs)

#         stop=time.time()

#         print('run time is %s' %(stop - start))

#         return res

#     return wrapper

#

# @timmer # index=timmer(index)

# def index():

#     print('welcome to index')

#     time.sleep(3)

#     return 123

#

# @timmer # home=timmer(home)

# def home(name):

#     print('welcome %s to home page' %name)

#     time.sleep(2)

#

# res=index()

# home('egon')

def deco(func):

    def wrapper(*args,**kwargs):

        res=func(*args,**kwargs)

        return res

    return wrapper

 

 

有参装饰器

 

import time

 

current_user={'user':None}

 

def deco(func):

    def wrapper(*args,**kwargs):

        if current_user['user']:

            #已经登陆过

            res = func(*args, **kwargs)

            return res

        user=input('username>>: ').strip()

        pwd=input('password>>: ').strip()

        if user == 'egon' and pwd == '123':

            print('login successful')

            # 记录用户登陆状态

            current_user['user']=user

            res=func(*args,**kwargs)

            return res

        else:

            print('user or password error')

    return wrapper

 

@deco

def index():

    print('welcome to index page')

    time.sleep(1)

 

@deco

def home(name):

    print('welecome %s to home page' %name)

    time.sleep(0.5)

 

 

index()

home('egon')

'''

 

'''

 

def f1():

    x=1

    def f2():

        def f3():

            print(x)

        return f3

    return f2

 

f2=f1()

 

f3=f2()

 

f3()

 

'''

 

 

import time

current_user={'user':None}

def auth(engine='file'):

    def deco(func):

        def wrapper(*args,**kwargs):

            if current_user['user']:

                #已经登陆过

                res = func(*args, **kwargs)

                return res

            user=input('username>>: ').strip()

            pwd=input('password>>: ').strip()

            if engine == 'file':

                # 基于文件的认证

                if user == 'egon' and pwd == '123':

                    print('login successful')

                    # 记录用户登陆状态

                    current_user['user']=user

                    res=func(*args,**kwargs)

                    return res

                else:

                    print('user or password error')

            elif engine == 'mysql':

                print('基于mysql的认证')

            elif engine == 'ldap':

                print('基于ldap的认证')

            else:

                print('无法识别认证来源')

        return wrapper

    return deco

 

@auth(engine='mysql') # @deco #index=deco(index) #index=wrapper

def index():

    print('welcome to index page')

    time.sleep(1)

 

@auth(engine='mysql')

def home(name):

    print('welecome %s to home page' %name)

    time.sleep(0.5)

 

 

index()

home('egon')

 

 

迭代器

'''

1、什么是迭代器

    迭代器即迭代取值的工具

    迭代:

        迭代是一个重复的过程,每一次重复都是基于上一次的结果而来的

 

        单纯的重复并不是迭代

        while True:

            print('1111')

 

        迭代:

        l=['a','b','c']

 

        def iterator(item):

            i=0

            while i < len(item):

                print(l[i])

                i+=1

 

 

2、 为什么要有迭代器

    基于索引的迭代器取值方式只适用于列表、元组、字符串类型

    而对于没有索引的字典、集合、文件,则不在适用

    所以必须找到一种通用的并且不依赖于索引的迭代器取值方式=》迭代器

 

    迭代器适用于可迭代的类型

 

3、如何用迭代器

 

 

'''

# l=['a','b','c']

# i=0

# while i < len(l):

#     print(l[i])

#     i+=1

 

# l = ['a', 'b', 'c']

# s='hello'

#

# def iterator(item): #item='hello'

#     i = 0

#     while i < len(item):

#         print(item[i])

#         i += 1

# # iterator(l)

# iterator(s)

 

 

# 可迭代的对象:在python中但凡内置有__iter__方法的对象都是可迭代的对象

# 字符串、列表、元组、字典、集合、文件都是可迭代的对象

# num1=10

# num2=10.1

# s1='hello'

# l=[1,2,3]

# t=(1,2,3)

# d={'x':1}

# s2={1,2,3}

# f=open('a.txt','w')

#

# s1.__iter__

# l.__iter__

# t.__iter__

# d.__iter__

# s2.__iter__

# f.__iter__

 

 

#

#

# 迭代器对象:指的是既内置有__iter__方法,又内置有__next__方法的对象

#执行可迭代对象的__iter__方法得到的就是内置的迭代器对象

# 文件对象本身就是迭代器对象

 

#强调:

#1、迭代器对象一定是可迭代的对象,反之则不然

 

 

 

# info={'name':'egon','age':18,'is_beautiful':True,'sex':'male'}

# info_iter=info.__iter__()

# # print(info_iter)

#

# res1=info_iter.__next__()

# print(res1)

#

# res2=info_iter.__next__()

# print(res2)

#

# res3=info_iter.__next__()

# print(res3)

#

# res4=info_iter.__next__()

# print(res4)

#

# info_iter.__next__() # 一旦迭代器取值取干净,再继续取就会抛出StopIteration

 

 

 

# info={'name':'egon','age':18,'is_beautiful':True,'sex':'male'}

# # info=[1,2,3,4,5]

# info_iter=info.__iter__()

# while True:

#     try:

#         print(info_iter.__next__())

#     except StopIteration:

#         break

 

 

#for循环:迭代器循环

# info={'name':'egon','age':18,'is_beautiful':True,'sex':'male'}

#in后跟的一定要是可迭代的对象

# for k in info: # info_iter=info.__iter__()

#     print(k)

 

# f=open('a.txt','r')

# for k in f:

#     print(k)

 

 

# 迭代器对象:指的是既内置有__iter__方法,又内置有__next__方法的对象

# 执行迭代器对象的__next__得到的是迭代器的下一个值

# 执行迭代器对象的__iter__得到的仍然是迭代器本身

 

# iter_info=info.__iter__()

# # print(iter_info)

# print(iter_info is iter_info.__iter__() is iter_info.__iter__().__iter__().__iter__().__iter__().__iter__())

#

 

 

#总结迭代器对象的优缺点:

#优点:

1、提供了一种通用的、可以不依赖索引的迭代取值方式

2、迭代器对象更加节省内存

 

 

 

 

# 缺点:

#1、迭代器的取值不如按照索引的方式更灵活,因为它只能往后取不能往前退

#2、无法预测迭代器值的个数

# names=['egon','alex_SB','wxx_SB']

# iter_names=iter(names)

# print(next(iter_names))

 

生成器

'''

 

1 什么是生成器?

在函数内但凡出现yield关键字,再调用函数就不会执行函数体代码,会返回值一个值,该值称之为生成器

 生成器本质就是迭代器

 

2、为什么要有生成器?

    生成器是一种自定义迭代器的方式

 

3、如何用生成器

 

 

'''

 

 

 

# def func():

#     print('first1')

#     print('first2')

#     print('first3')

#     yield 1 #暂停

#     print('second1')

#     print('second2')

#     print('second3')

#     yield 2  #暂停

#     print('third')

#     yield 3 #暂停

#     print('fourth')

#

# g=func()

# print(g)

# print(g.__iter__().__iter__().__iter__() is g)

# res1=next(g)

# print('第一次的返回值:',res1)

#

# print('='*100)

# res2=next(g)

# print('第二次的返回值:',res2)

#

# print('='*100)

# res3=next(g)

# print('第三次的返回值:',res3)

#

# print('='*100)

# res4=next(g)

# print('第三次的返回值:',res4)

 

# for item in g: #g=iter(g) #item=next(g)

#     print(item)

 

# i=range(1,1000)

# for item in range(1,1000000000)

 

 

 

# def my_range(start,stop,step=1):

#     while start < stop:

#         yield start # 暂停

#         start+=step

# g=my_range(1,5,2) #1 3

 

 

# print(next(g))

# print(next(g))

# print(next(g))

# print(next(g))

# print(next(g))

# print(next(g))

# print(next(g))

 

# for item in g:

#     print(item)

 

 

#总结yield的功能

#1、提供一种自定义迭代器的方式

#2、yield可以暂停住函数,返回值

 

#yield  VS return

#相同点:都是用在函数内,都可以返回值,没有类型限制,没有个数限制

#不同点:return只能返回一次值,yield可以返回多次值

 

 

# 了解知识

# yield 值

# x=yield

# x= yield 值

 

def dog(name):

    food_list=[]

    print('狗哥 %s 准备开吃' %name)

    while True:

        food=yield food_list#暂停 food=yield='一桶泔水'

        print('狗哥[%s]吃了<%s>' %(name,food))

        food_list.append(food)

 

 

alex_dog=dog('alex')

 

res1=next(alex_dog) # 初始化,即让狗准备好

print(res1)

# next(alex_dog) # 等同于alex_dog.send(None)

#

# next(alex_dog)

 

res2=alex_dog.send(('一泡翔','咖啡伴侣'))

print(res2)

 

res3=alex_dog.send('一桶泔水')

print(res3)

#

 

 

# 列表生成式

# l=[item**2 for item in range(1,11)]

# print(l)

 

 

# names=['alex','wxx','lxx']

 

# l=[]

# for name in names:

#     l.append(name + 'SB')

# names=l

 

# names=[name+'SB' for name in names]

# print(names)

 

 

# names=['alex','wxx','egon','lxx','zhangmingyan']

# l=[]

# for name in names:

#     if name != 'egon':

#         l.append(name + 'SB')

# names=l

# names=[name+'SB' for name in names if name != 'egon']

# print(names)

 

 

# l=[item**2 for item in range(1,5) if item > 2]

# print(l)

 

# names=['egon','alex_sb','wupeiqi','yuanhao']

# names=[name.upper() for name in names]

# print(names)

# names=['egon','alex_sb','wupeiqi','yuanhao']

#

# nums=[len(name) for name in names if not name.endswith('sb')]

# print(nums)

 

 

#字典生成式

# s1='hello'

# l1=[1,2,3,4,5]

 

# res=zip(s1,l1)

# print(res)

# print(list(res))

 

 

# keys=['name','age','sex']

# values=['egon',18,'male']

 

# res=zip(keys,values)

# print(list(res))

# print(list(res))

# d={}

# for k,v in zip(keys,values):

#     d[k]=v

# print(d)

 

# keys=['name','age','sex']

# values=['egon',18,'male']

# d={k:v for k,v in zip(keys,values)}

# print(d)

 

info={'name': 'egon', 'age': 18, 'sex': 'male'}

 

keys=info.keys()

# print(keys)

# iter_keys=keys.__iter__()

# values=info.values()

# print(values)

 

 

 函数递归

 

1 什么是函数递归

    函数递归调用(是一种特殊的嵌套调用):在调用一个函数的过程中,又直接或间接地调用了该函数本身

 

    递归必须要有两个明确的阶段:

        递推:一层一层递归调用下去,强调每进入下一层递归问题的规模都必须有所减少

        回溯:递归必须要有一个明确的结束条件,在满足该条件时结束递推

            开始一层一层回溯

 

    递归的精髓在于通过不断地重复逼近一个最终的结果

 

2、为什么要用函数递归

 

 

3、如何用

'''

 

 

# import sys

# print(sys.getrecursionlimit())

# sys.setrecursionlimit(3000)

# def foo(n):

#     print('from foo',n)

#     foo(n+1)

# foo(0)

 

# def bar():

#     print('from bar')

#     foo()

#

# def foo():

#     print('from foo')

#     bar()

 

# foo()

 

# age(5) = age(4) + 2

# age(4) = age(3) + 2

# age(3) = age(2) + 2

# age(2) = age(1) + 2

# age(1) = 26

 

# age(n) = age(n-1) + 2 #n > 1

# age(1) = 26           #n = 1

 

 

# def age(n):

#     if n == 1:

#         return 26

#     return age(n-1) + 2

#

# print(age(5))

 

 

# l=[1,[2,[3,[4,[5,[6,[7,[8,[9,]]]]]]]]]

#

# def tell(l):

#     for item in l:

#         if type(item) is list:

#             #继续进入下一层递归

#             tell(item)

#         else:

#             print(item)

#

# tell(l)

 

# 有一个从小到大排列的整型数字列表

# nums=[1,3,7,11,22,34,55,78,111,115,137,149,246,371]

# 10 in nums

# for item in nums:

#     if item == 10:

#         print('find it')

#         break

# else:

#     print('not exists')

nums=[1,3,7,11,22,34,55,78,111,115,137,149,246,371]

def search(search_num,nums):

    print(nums)

    if len(nums) == 0:

        print('not exists')

        return

    mid_index=len(nums) // 2

    if search_num > nums[mid_index]:

        # in the right

        nums=nums[mid_index+1:]

        search(search_num,nums)

    elif search_num < nums[mid_index]:

        # in the left

        nums=nums[:mid_index]

        search(search_num,nums)

    else:

        print('find it')

 

匿名函数

 

 

# 有名函数:基于函数名重复使用

# def func():

#     print('from func')

 

# func()

# func()

# func()

 

 

# 匿名函数:没有绑定名字的下场是用一次就回收了

# def func(x,y): #func=函数的内存地址

#     return x + y

 

# res=(lambda x,y:x+y)(1,2)

# print(res)

 

# f=lambda x,y:x+y

# print(f)

# print(f(1,2))

 

#max min map filter sorted

salaries={

    'egon':3000,

    'alex':100000000,

    'wupeiqi':10000,

    'yuanhao':2000

}

 

# max的工作原理

#1 首先将可迭代对象变成迭代器对象

#2 res=next(可迭代器对象),将res当作参数传给key指定的函数,然后将该函数的返回值当作判断依据

# def func(k):

#     return salaries[k]

#

# print(max(salaries,key=func)) #next(iter_s)

#'egon', v1=func('egon')

#'alex', v2=func('alex')

#'wupeiqi', v3=func('wupeiqi')

#'yuanhao', v4=func('yuanhao')

 

 

 

# salaries={

#     'egon':3000,

#     'alex':100000000,

#     'wupeiqi':10000,

#     'yuanhao':2000

# }

# print(max(salaries,key=lambda k:salaries[k])) #next(iter_s)

# print(min(salaries,key=lambda k:salaries[k])) #next(iter_s)

 

 

# l=[10,1,3,-9,22]

# l1=sorted(l,reverse=False)

# print(l1)

 

# l2=sorted(l,reverse=True)

# print(l2)

 

# salaries={

#     'egon':3000,

#     'alex':100000000,

#     'wupeiqi':10000,

#     'yuanhao':2000

# }

#

# print(sorted(salaries,key=lambda k:salaries[k],reverse=True))

 

names=['张明言','刘华强','苍井空','alex']

 

# map的工作原理

#1 首先将可迭代对象变成迭代器对象

#2 res=next(可迭代器对象),将res当作参数传给第一个参数指定的函数,然后将该函数的返回值当作map的结果之一

# aaa=map(lambda x:x+"_SB",names)

# print(aaa)

# print(list(aaa))

 

# print([name+"_SB" for name in names])

 

# filter的工作原理

#1 首先将可迭代对象变成迭代器对象

#2 res=next(可迭代器对象),将res当作参数传给第一个参数指定的函数,然后filter会判断函数的返回值的真假,如果为真则留下res

names=['alexSB','egon','wxxSB','OLDBOYSB']

 

# print([name for name in names if name.endswith('SB')])

 

aaa=filter(lambda x:x.endswith('SB'),names)

print(aaa)

print(list(aaa))

 

内置方法

abs() 求一个数字的最大值

bytes() 将一个字符串转换成一个bytes类型

bool()给出一个数据的布尔值

min()求出最小的值参数必须是可迭代对象  其中可跟lambda匿名函数的参数

max()求出最大的值参数必须是可迭代对象  其中可跟lambda匿名函数的参数

sum()求出总和参数必须是可迭代对象 其中可跟lambda匿名函数的参数

zip()将两个可迭代的数据每一次next取出一个数据将两者拼接成一个个的小元组

chr()将一个Ascll码转换成为一个对应的字符

ord()chr的反向操作

otc()讲一个十进制数字转换成八进制数字

bin()将一个十进制数字转换成二进制数字

hex() 讲一个十进制数字转换成十六进制数字

int()将一个字符串转换成一个十进制数字  或者将一个二进制八进制十六进制字符串  转换成十进制数字可以,通过int(‘101010101’,2)其中2代表字符串代表的是一个二进制字符数字,

list()讲一个可迭代对象里面的值一个个取出生成一个列表

__import__()与import不同的是该方法可以将字符串代表的模块名导入程序例如 x = __import('time')

eval()可以将一个字符串中的列表字典等数据提取出来

open()用于建立一个文件的读取管道

dir()获取模块中的方法名

help()获取函数中的注释

type()查看数据类型

 

posted on 2018-06-05 22:27  阿乐的博客园  阅读(193)  评论(0编辑  收藏  举报

导航