函数 装饰器 生成器 面向过程编程

"""
# 齐天大圣孙悟空身如玄铁 火眼金睛 长生不老还有七十二变
定义函数与调用函数的基本形式

一 ,函数定义的三种形式

1.1 无参函数

def foo():
    print('hello word ')
foo()

1.2有参函数
def foo(x,y):
    print(x,y)

foo(1,2)
1.3 空函数
def f1():
    pass
def f2():
    pass
View Code

调用函数的三种形式

2.1语句形式
2.1 #语句形式
def foo():
    print('from foo')
foo()

2.2 表达式形式

2.2 表达式形式
def foo(x,y):
    res = x + y
    return res

res=foo(1,2) #表达式形式
res1=foo(1,2)*100
print(res1)


2.3 可以当做参数传给另一个函数

def max2(x,y):
    if x > y:
        return x
    else:
        return y

1 2 3
res=max2(max2(1,2),3)
print(res)
View Code

二:函数的返回值

1 函数的返回值需要注意:
1返回值没有类型限制
2返回值没有个数限制
3
3.1 返回一个值,调用函数拿到的就是一个值
3.2 返回多个值,调用函数拿到的就是一个元祖
3.3 返回0个值,或者不写return 调用函数拿到的结果就是None


2 return 关键字:return是函数结束的标志,函数内可以有多个return
但是只要执行一次,整个函数就会结束

# def foo():
# print("111")
# return
# print('333')
# return
# foo()
上面的函数虽然内部有多个return,但是只会执行第一个return,便会结束整个函数



三:函数参数的使用:
函数的参数分为两大类
1.形参:数阶段指的是在定义函括号内指定的变量名,形参本质--变量名
2.实参:指的是在函数调用阶段传入括号内的值,实参本质--值

形参与实参的关系:在调用函数时,会将实参(值)赋值(绑定)给形参(变量名)
这种绑定关系只是在调用函数时临时有效,在调用结束后就失效了


def foo(x,y):
print(x,y)#x,y就是 形参
return x+y #返回值会绑定给函数 此时函数调用结束之后函数的一个结果

res=foo(1,2) #调用foo函数
print(res) # 打印调用函数的返回值

函数的参数的分类
# 形参和实参的具体分类
一:位置参数
1.1 位置形参:在定义函数阶段按照从左到右的顺序依次定义的形参
注意:凡是按照位置传值得形参,即位置形参,必须被传值,多一个少一个都不行


def foo(x,y):  #此处的x,y皆为位置形参
    print(x,y)

foo(1,2) #此处的x,y皆为位置实参


1.2位置实参:在函数调用阶段按照从左到右的顺序依次传入的值,叫做位置实参
注意:凡是按照位置定义的实参,会与形参意义对应


二:关键字参数:
关键字实参:在调用阶段,按照key=value 的形式指名道姓的为形参传值
注意:
    1.可以完全打乱顺序,但仍然能指名道姓的为指定的形参传值
    2可以混合使用位置实参和关键字实参,但是必须的注意:
        2.1 位置参数必须放到关键字实参的前面
        2.2 不能对一个形参重复赋值

def foo(name,age):
    print(name,age)

foo(name='andy',age=21) #按照关键字实参为形参指名道姓的传值
foo(age=21,name='andy') #顺序发生变法关键字实参依然可以为形参传值
foo('andy',21) #按照位置传值也可以


三:默认参数
默认参数 :指的是在定义函数阶段,就已经为某个形参赋值了,将形参改为有默认值的形参,简称为默认形参
注意:
    1.在定义阶段就已经被赋值,意味着在调用阶段可以不为赋值
    2.位置形参应该放到默认形参前面
    3默认参数的值在通常情况下是不可变类型(要是想改变,在调用阶段为其传值即可)



    位置形参vs 默认形参

    对于大多数情况下值不相同的,应该被定义为位置形参
    对于大多数情况下的值是相同的,应该被定义为默认参数(比如人的分类)


def classify('name','age','hight','sex'=男):
    print(name,age,hight,sex)

classify('张三','12','129')
classify('李四','15','192')
classify('王五','17','180')
classify('小猪','18','172','')



四:可变长参数站在实参的角度,参数长度指的是再调用函数时, 传入实参值的个数不固定
而实参的定义方式无非两种:位置实参和关键字实参对应着形参也必须有两解决方案*与**,
类分别应对溢出的位置实参

1.在形参中带* 会将调用的函数溢出的部分保存成元祖的形式,然后复制给*后面的变量名

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

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

2.在实参中带*,但凡 在实参中带*,在传值之前都先将其打散成位置实参,再进行赋值
def foo(x,y):
    print(x,y)

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



3.在实参中带**,但凡在实参中带**号,在传值之前会将其打散成关键字实参,在再进行赋值
4.在形参中dai**,但凡在形参中带**号,会将调用函数时溢出的关键词实参保存成字典的格式,
然后赋值给**号后面的变量名


#5. 规范: 在形参中带*与**的,*后的变量名应该为args,**后跟的变量名应该时kwargs

"""
View Code
# 函数是第一类对象:指的是函数名指向的值(函数)可以被当做数据去使用

# def func(): # func=函数的内存地址
#     print('hello word')
#
# print(func())
View Code
#  函数的对象可以被引用.
# 可以当做参数传给另外一个函数
# 可以当做一个函数的返回值
# 可以当做容器类型的元素

# 举一个小栗子:

'''

def login():
    print("登录")
def register():
    print("注册")

def shopping():
    print("购物")

def pay():
    print("付钱")

def tramsfer():
    print("transfer")

dic={
    '1':login,
    '2':register,
    '3':shopping,
    '4':pay,
    '5':tramsfer


}
msg="""
0 退出
1 登陆
2 注册
3 购物
4 支付
5 转账
"""
while True:
    print(msg)
    choice=input("请输入你的选择")
    if choice == '0':
        break
    if choice in dic:
        dic[choice]()

    else:
        print("请重新输入")
'''
View Code

# 函数的嵌套分为两大类
# 一:函数的嵌套调用,在调用一个函数的过程程中,其内部的代码又调用了其他函数

# def bar():
#     print('bar')
#
# def foo():
#     print('foo')
#     bar()
# foo()
#


# 举一个小栗子:
# def max1(x,y):
#     return  x if x>y else y
# def max2(a,b,c,d):
#     res1=max1(a,b)
#     res2=max1(res1,c)
#     res3=max1(res2,d)
#     return res3
# l=max2(2,4,5,6)
# print(l)
#
函数的调用

# 二:函数的嵌套定义:一个函数的内部又定义了另外一个函数

# def foo():
# print("f1")
# def f2():
# print('f2')
# def f3():
# print('f3')
# return f3()
# return f2()
#
# foo()
#
# 举一个小栗子:

# 计算圆的面积和周长

'''
from math import pi
def lll(r,action=0):
    """
    计算圆的面积和周长
    :param r:传入圆的半径
    :param action:传入你要选个的数 ,
    :return:     返回选1就是面积,选2 就是周长
    """
    def area(r):
        return  pi*(r**2)
    def perimeter(r):
        return 2*pi*r
    if action==1:
        return area(r)
    elif action=='2':
        return  perimeter(r)


print("下面是你的选择界面")
radius=int(input("请输入你要计算的圆的半径")     )
inp=int(input("请输入你要选择的方面1 面积  2'周长")    )

res=lll(radius,inp)
print(res)

      '''
View Code

# 名称空间和作用域:
# 1.什么是名称空间namespace

# 名称空间就是用来存放名字与值内存地址绑定关系的地方()内存空间
# 但凡 查找值一定要通过名字,访问名字必须去查找名称空间
#
# 2.名称空间分为三大类

内置名称空间 :存放的是Python解释其自带的名字
全局名称空间: 存放的是文件级别的名字
局部名称空间 :在函数内定义的名字

# 生命周期:
# 内置名称空间 :在解释器启动时则生效,解释器关闭则失效
# 全局名称空间 在解释器解释执行python文件时则生效,文件执行完毕后则失效
# 局部名称空间 只在调用函数时临时产生该函数的局部名称空间,改函数调用完毕则失效
# 加载顺序:
# 内置--全局--局部
#
# 查找名字顺序
# 基于当前所在位置往上查找
# 假设当前站在局部,查找顺序:局部--全局--内置名称空间
# 假设站在全局 全局--内置

# (******)名字的查找顺序,在函数定义阶段就已经固定死了(即在检测语法时就已经确定了名字的查找顺序),与函数的调用位置无关,也就是说无论在任何地方调用函数,都必须回到
# 当初定义函数的位置去确定名字的查找关系


'''
# 案列一:
# # len=111
#
# def foo():
#     len=222
#     print(len)
#
# foo()
# print('站在全局找len: ',len)


# x=111
#
# def f1():
#     x=222
#     def f2():
#         def f3():
#             # x=444
#             print(x)
#         x=333
#         f3()
#     f2()
# f1()
View Code


# 案列二:
# x=111
# def outer():
#     def inner():
#         print('from inner',x) # x访问的时全局名称空间中x
#     return inner
#
# f=outer()
# # print(f)
#
# x=222
# f()


# 案列三:
# x=111
# def outer():
#     def inner():
#         print('from inner',x) # x访问的时全局名称空间中x
#     return inner
#
# f=outer()
#
# # x=222
# def func():
#     x=333
#     f()
#
# x=444
#
# func()


# 案列四:
# x=111
# def outer():
#     def inner():
#         print('from inner',x) # x是来自于当前层的名字
#         x=2222222222
#     return inner
#
# f=outer()
#
# f()
'''
案例二三四


# 作用域:
# 域指的是范围,作用域指的就是作用的范围,分为两种
#
# 全局作用域:包含的是内置名称空间与全局名称空间中的名字
# 特点:全局有效,全局存活
#
# 局部作用域:包含的是局部名称空间中的名字
# 特点:局部有效,临时存活
# 举一个小栗子

"""
# global,nonlocal

# x=1
# def foo():
#     x=2
#
# foo()
# print(x)


# l=[]
# def foo():
#     l.append(1)
#     # l=33333
# foo()
# print(l)

#global:在局部声明一个名字是来自于全局作用域的,可以用来在局部修改全局的不可变类型
# x=1
# def foo():
#     global x
#     x=2
#
# foo()
# print(x)

#nonlocal:声明一个名字是来自于当前层外一层作用域的,可以用来在局部修改外层函数的不可变类型
x=0
def f1():
    x=111
    def f2():
        # global x
        nonlocal x
        x=222
    f2()
    print(x)

f1()
# print(x)

"""
作用域

# 闭包函数(******)

# 什么是闭包函数?
# # 闭:指的是闭包函数是定义在一个函数内部的函数
# 包:该内部函数包含对外层函数作用域名字的引用
# 需要结合函数对象的概念将闭包函数返回到全局作用域去使用
#
# 闭包函数范例:
# def outter():
# x=11
# def inner():
# print("inner")
# return inner
#
# f=outter()
# f()
#
# 2 为何要用闭包函数
# 闭包函数提供了一种为函数体传值的解决方案
#
#
# 3 如何用闭包函数
# 为函数体传值的方式一:参数
# def func(x,y):
# print(x+y)
#
# func(1,2)

# 为函数体传值的方式二:闭包
# def outter(x,y):
# # x=1
# # y=2
# def func():
# print(x+y)
# return func
#
# f=outter(1,2)
# f()
# f()

"""
# 解决方案一:参数

def get(url):
    response=requests.get(url)
    if response.status_code == 200:
        print(len(response.text))

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

# url1='https://www.baidu.com'
# url2='https://www.tmall.com'
#
# get(url1)
# get(url1)
# get(url1)
#
# get(url2)
# get(url2)
# get(url2)
#
参数


# 解决方案二:闭包

# def outter(url):
#     # url='https://www.baidu.com'
#     def get():
#         response=requests.get(url)
#         if response.status_code == 200:
#             print(len(response.text))
#     return get
#
# baidu=outter('https://www.baidu.com')
# baidu()
# baidu()
# baidu()
#
# tmall=outter('https://www.tmall.com')
# tmall()
# tmall()
"""
闭包
# 补充:所有的数据类型的值自带布尔值,可以直接当作条件去用,只需要记
# 住布尔值为假的那一些值即可(0,空,None)
import time
current_user={'username':None}
def login(engine='file'):
    def auth(func):
        def wrapper(*agrs,**kwargs):
            if current_user['username']:
                print('已经登陆过了')
                res = func(*agrs,**kwargs)
                return res
            if engine=='file':
                user=input("请输入你的用户名")
                pwd=input("请输入密码")
                if user=='andy' and pwd=='123':
                    print("登陆成功")
                    current_user['username']=user
                    res=func(*agrs,**kwargs)
                    return res
                else:
                    print("username or password error")

            elif engine=='mysql':
                print("基于mysql的认证机制")
            elif engine=='ldap':
                print('基于ldap的认证机制')
            else:
                print("无法识别的认证源")
        return wrapper
    return auth

@login('mysql')
def index():
    print("welcome to index page")
    time.sleep(3)

index()
egon总结装饰器

1.什么是装饰器
器:指的是具备某一功能的工具
装饰:指的是为被装饰器对象添加新功能

装饰器本身就是用来为被装饰对象添加新功能的工具
注意: 装饰器本身可以是任意的可调用对象,被装饰器也可以是任意可
调用对象

2.为何要用装饰器:
开放封闭原则:封闭指的是对修改封闭,开放就是对扩展开放
装饰器的实现必须遵循两大原则:
1.不能修改被装饰对象的源代码
2.不能修改被装饰对象的调用方式


怎么用装饰器

装饰器的语法糖:
在装饰器对象正上方单独一行写装饰器的名字
运行原理:
Python解释器一旦运行到@装饰器的名字,就会调用装饰器,,然后将被装饰函数的
内存地址当做参数传给装饰器,最后将装饰器的结果赋值给元函数名
无参装饰器下面是一种调用方式(被装饰函数有参合无参)


"""
import  time


def outter(func):
    def inner(*args,**kwargs):
        print("这里是装饰器")
        start_time=time.time()
        res=func(*args,**kwargs)
        stop_time=time.time()
        print("所用时间是%s"%(stop_time-start_time))

    return inner
# @outter
# def index():
#     print("快点叫爸爸")
#     time.sleep(3)

@outter
def home(name):
    print("快点回家%s"%name)
    time.sleep(1)


home('andy')
# index()

"""
被装饰函数有无参数



无参装饰器的模板

def outter(func): # func=foo  被装饰函数的地址
    def inner(*args,**kwargs): #括号里面是被装饰函数的参数
        #这个地方填上被装饰函数前面要添加的东西
        res=func(*args,**kwargs)  #此时的func ()就是调用foo函数,并将韩绘制赋值给res
        #这个地方添加被装饰函数后面要添加的东西
        return res
    return inner

@outter
def foo():
    print("hello word")
    return 'foo 函数的返回值'

foo()
无参装饰器模板




调用的函数无参数,有参数都像上面这样,
调用的函数为有参函数的参数会传给*args 和 **kwargs 里面剩下的跟无参函数一样

举例个小例子

import time
def auth(func):
    def wrapper(*args,**kwargs):
        username=input("please input you username ")
        password=input("please input you password")
        if username=='andy'and password =='123':
            print("登陆成功")
            start_time=time.time()
            res=func(*args,**kwargs)
            stop_time = time.time()
            print("中间的时间间隔是%s"%(stop_time-start_time))

            return res
        else:
            print("登录失败")

    return wrapper

#下面是装饰一个无参函数
# @auth
# def index():
#     print("这是一个被调用的函数")
#     time.sleep(3)
#     return '加油,少年'



#下面是装饰一个有参函数
@auth
def home(age):
    print("我的年龄是%s"%age)
    time.sleep(1)
    return '加油'


# print(index())  #无参时的调用
print(home('欧阳')) #有参时候的调用



"""
View Code


有参装饰器后面括号里面加上参数 即@outter('name')的格式
模板:
"""

def auth(x): # 此处的x 就是装饰器里面传来的参数
    def outter(func):  # 此时的func 就是以前foo的内存地址
        def inner(*args,**kwargs): # inner里面的参数就是 foo里面的参数
            res=func(*args,**kwargs)  #执行以前的foo函数
            return res 
        return inner # 此时的inner就是foo
    return outter

@auth(1)
def foo(name):
    print("hello word")
    return '加油'

foo('ouyang')
    """





有参函数的演示,是为了在装饰函数时有多的参数拿来调用

"""
def auth(x):  # 此处的x 就是装饰器里面传来的参数
    def outter(func):  # 此时的func 就是以前foo的内存地址
        def inner(*args, **kwargs):  # inner里面的参数就是 foo里面的参数
            if x=='1':
                res = func(*args, **kwargs)  # 执行以前的foo函数
                return res
            else:
                print("我本可以更强大,只是压力不够")

        return inner  # 此时的inner就是foo

    return outter


@auth('1')
def foo(name):
    print("hello word %s"%name)
    return '加油'


foo('ouyang')
"""
View Code


# 1.什么是函数的递归

# 函数的递归调用是函数嵌套调用的一种特殊形式,在调用函数的过程中又直接或者间接调用该函数
# 本身,称之为函数的递归调用(自解:就是函数嵌套阶段,会调用到本身的函数)
# 2.递归调用必须有两个明确的阶段:
# 1.回溯:一的规次次递归调用下去,说白了就是一个重复的过程,但需要注意得失每一次重复问题模
# 都应该有所减少,直到逼近一个最终的结果,即回溯阶段一定要有一个明确的结束条件
# (自解:递归的事物在重复中减少,在条件作用下直到拿到一个结果)
#
# 2.递推:往回一层层的推算出结果(回推)
#
# 总结以上,递归函数就是嵌套函数,只是在执行函数过程中会调用到自身的函数,有回溯和递推两个阶段(有来有回)
#
#
#
# 假如a的年龄加二是b的年龄,b的年龄加二是c的年龄...e的年龄是18,求a的年龄


# age(5)=18  age4=age(3)+2
# def age(n):
#     if n==5:
#         return 18
#     return age(n+1)-2
#
# # age(5)
# print(age(1))
递归猜年龄




# 打印列表里面的元素
# l=[1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,]]]]]]]]]]]
# def foo(l):
# for i in l:
# if type(i) is not list:
# print(i)
# else:
# foo(i)
#
# foo(l)

# 三元表达式: 条件成立返回一个值,条件不成立返回另外一个值

# name=input('user').strip()
# res='loser' if name=='andy' else '强大'
# print(res)
"""

# def foo(x,y):
#     if x>y:
#         return x
#     else:
#         return y
#
# foo(1,2)

# def max1(x,y):
#     return x if x > y else y
#
# print(max1(1,2))

# name=input('user').strip()
# res='loser' if name=='andy' else '强大'
# print(res)
# 

"""
三元表达式

# 列表生成式

# names=['alex','lqz','yyh','fm']
# l=[]
# for i in names:
# res=i+'_dsb'
# l.append(res)
#
# print(l)

# 生成式如下:

# l=[name+'dsb' for name in names ]
# print(l)


# 将下面列表里面的元素后面有dsb的添加到另外的列表
# names=['alex_dsb', 'lqz_dsb', 'yyh_dsb', 'fm_dsb','andy','ouyang']
# l=[]
# for name in names:
#     if name.endswith('dsb'):
#         l.append(name)
#
# print(l)

# 列表生成式如下
# l=[name for name in names if name.endswith('dsb')  ]
# print(l)

# 补充,为列表加上序号
# dic={key:vals[x] for x,key in enumerate(keys) }

# l=['a','b','c','d','e']
# for i,j in enumerate(l):
#     print(i,j)


keys=['name','age','sex']
vals=['egon',18,'male']
# dic={}
# for x,key in enumerate(keys):
#     dic[key]=vals[x]
# print(dic
#
# )

# dic={key:vals[x] for x,key in enumerate(keys) }
列表生成式和字典生成式

# 匿名函数
# 就是没有名字的函数
# 用于仅仅临时使用一次的场景
# 匿名函数的精髓就是没有名字,为其绑定名字没有意义

# def sum2(x,y):
# return x+y
#
# print(sum2(1,2))

# print((lambda x,y:x+y)(1,2))

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


# 匿名函数与内置函数结合使用
# max,min,sorted,map,filter,reduce





# 二分查找
l=[1,2,10,30,33,99,101,200,301,311,402,403,500,900,1000]
def foo(n,l):
print(l)
if len(l)==0:
print("不存在")
return
mid_index=len(l)//2
if n >l[mid_index]:
l=l[mid_index+1:]
foo(n,l)
elif n<l[mid_index]:
l=l[0:mid_index]
foo(n,l)
else :
print("%s在的"%n)

foo(9001,l)


迭代器

1. 什么是迭代器
1.1. 迭代器指的是迭代取值的工具


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


#单纯的重复不是迭代
# i=0
# while True:
# print(i)


# 迭代:重复+每次重复都是基于上一次的结果而进行
l=['a','b','c']
i=0
while i < len(l):
print(l[i])
i+=1


2. 为何要用迭代器
迭代器提供了一种通用的且不依赖于索引的迭代取值方式


3. 如何用迭代器



'''

# l=['a','b','c']
# l='hello'
# l=('a','b','c')
# i=0
# while i < len(l):
# print(l[i])
# i+=1

#一 :可迭代的对象iterable:但凡内置有__iter__方法的对象都称之为可迭代的对象
#可迭代的对象:str,list,tuple,dict,set,文件对象
# a=1
# b=1.1
# c='hello'
# d=['a','b']
# e=('a','b')
# j={'x':1}
# g={1,2,3}
# f=open('a.txt','w')



# 执行可迭代对象下的__iter__方法,返回的值就是一个迭代器对象iterator


# dic={'x':1,'y':2,'z':3}
# iter_dic=dic.__iter__()
#
# # print(iter_dic)
# print(iter_dic.__next__())
# print(iter_dic.__next__())
# print(iter_dic.__next__())
# print(iter_dic.__next__()) #StopIteration应该被当成一种结束信号

 

# f=open('a.txt','rt',encoding='utf-8')
# iter_f=f.__iter__()
# print(iter_f.__next__())
# print(iter_f.__next__())
# print(iter_f.__next__())
# print(iter_f.__next__())


# l=['a','b','c']
# iter_l=l.__iter__()
#
# print(iter_l.__next__())
# print(iter_l.__next__())
# print(iter_l.__next__())
# print(iter_l.__next__())

 

# l=['a','b','c']
# print(l.__iter__().__next__())
# print(l.__iter__().__next__())
# print(l.__iter__().__next__())
# iter_l=l.__iter__()
# print(iter_l.__next__())
# print(iter_l.__next__())

 

#二: 迭代器对象
#1. 既内置有__next__方法的对象,执行迭代器__next__方法可以不依赖索引取值
#2. 又内置有__iter__方法的对象,执行迭代器__iter__方法得到的仍然是迭代器本身
# ps:
# 1.迭代器对象一定是可迭代的对象,而可迭代的对象却不一定是迭代器对象
# 2.文件对象本身就是一个迭代器对象
# l=['a','b','c']
# iter_l=l.__iter__() # 调用可迭代的对象__iter__得到的是迭代对象,
# print(iter_l is iter_l.__iter__().__iter__().__iter__().__iter__().__iter__().__iter__())

# dic={1,2,3,4}
# dic={'x':1,'y':2,'z':3}
# # print(len(dic)) #dic.__len__()
# iter_dic=iter(dic) # dic.__iter__()
#
# while True:
# try:
# print(next(iter_dic)) #iter_dic.__next__()
# except StopIteration:
# break
#
# print('='*100)
# # 同一个迭代器只能完整地取完一次值
# iter_dic=iter(dic) #dic.__iter__()
# while True:
# try:
# print(next(iter_dic)) #iter_dic.__next__()
# except StopIteration:
# break


#for本质应该称之为迭代器循环
#工作原理
#1. 先调用in后面那个对象的__iter__方法,将其变成一个迭代器对象
#2. 调用next(迭代器),将得到的返回值赋值给变量名k
#3. 循环往复直到next(迭代器)抛出异常,for会自动捕捉异常然后结束循环

# ps:从for角度,可以分辨出但凡可以被for循环循环取值的对象都是可迭代的对象
# dic={'x':1,'y':2,'z':3}
#
# for k in dic:
# print(k)
#
# for k in dic:
# print(k)
View Code



#三:迭代器总结
# 优点:
# 1. 提供一种通用的且不依赖于索引的迭代取值方式
# 2. 同一时刻在内存中只存在一个值,更节省内存


# 缺点:
# 1. 取值不如按照索引的方式灵活,(不能取指定的某一个值,而且只能往后取)
# 2. 无法预测迭代器的长度



# l=[1,2,2,3,3,3,3,3,3,3,3,3,3,3]
# iter_l=iter(l)
# print(iter_l)


# names = ['egon', 'alex', 'yxx']
# res=map(lambda x:x+"_NB",names)
# print(res)


# obj=range(1,1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)
# print(obj)



 1 生成器; 生成器本身就是一种自定义的迭代器,本质就是迭代器
#
# 2 但凡函数内包含yield 关键字,调用函数不会执行函数体代码
# 会得到一个返回值,该返回值就是生成器对象

def func():
    print("111")
    yield 1
    print('222')
    yield 2

g=func()
res=next(g)
print(res)
View Code

# 3 res=next(g)会触发函数体的执行,直到碰到一个yield 停下来
# 并且将yield后的值当做本次next的结果返回

# 4 了解:yield 的表达形式的应用:x=yield
"""
def dog(name):
print("狗哥,%s 准备开吃"%name)
food_list=[]
while True:
food=yield food_list
print('%s 吃了 %s' %(name,food))
food_list.append(food)
# 强调:针对表达式形式的yield的使用,第一步必须让函数先暂停到一个yield的位置,才能进行传值操作
# next(g) # 张开狗嘴,让生成器先暂停到yield的位置,准备接收外部传进来的值
g=dog('alex')
res1=next(g)
res2=g.send('肉包子')
res3=g.send('菜包子')
print(res3)
"""

# 总结yield :只能在函数内使用
# 1 yield提供了一种自定义迭代器的解决方案
# yield可以保存函数的暂停状态
# yield对比return
# 1.相同点:都可以返回值,值得类型与个数都没有限制
# 2 不同点: yield介意返回多次值,二return只能返回依次值函数就结束了
#

# 5 生成器表达式

g=(i**2 for i in range(1,6) if i > 3)
print(g)
print(next(g))
print(next(g))



# with open('a.txt0,'w',encoding=''utf-8')as  f:
#     res=sum(len(line) for line in f)
#     print(res)
# print(abs(-1))
# print(all([1,'',None,False]))  #相当于and



# 6 内置函数

print(any)  #相当于or
bin  #十进制转二进制
oct  #十进制转八进制
hex  # 十进制转16进制

 print(bool(0))
res=bytes('大家好',encoding='utf-8')
print(res,type(res))

 print(bool(0))  #查看是不是个函数名
print(chr(65))
 print(chr(90))
字符和ascll码的联系和变换
 print(chr(97))
 print(chr(122))

 print(ord('a'))
 print(ord('z'))
 print(ord('@'))


 print(divmod(3003,20))设置页数


 for i in enumerate(['a','b','c']):
  print(i)  # for 循环时到序号

res=eval('[1,2,3]')  #eval 将转化而列表
print(res,type(res))


# 面向对象

object.__dict__

classmethod
staticmethod
property

delattr
hasattr
getattr
setattr

isinstance
issubclass
View Code





# 面向过程编程
# 核心是过程二字,过程指的就是解决问题的步骤,即先干什么再干什么后干什么
# 基于该思想编写程序就好比在设计一条流水线,是一种机械是的思维方式
#
# 优点:复杂的问题流程化,进而简单化
# 缺点:可扩展性差
#

# 代码实例,完成登录和注册


def talk():
    while True:
        username=input("please  input you username ")
        if username.isalpha():
            break
        else:
            print("用户名必须为字母")
    while True:
        password1=input("please input you password ")
        password2=input("please again input you password ")
        if password1 == password2:
            break
        else:
            print("两次输的密码不一致")

    role_dic={
        '1':'user',
        '2':'admin'
    }
    while True:
        for k in role_dic:
            print(k,role_dic[k])
        choice=input("请输入您的身份>>").strip()
        if choice not in role_dic:
            print("数人的身份不存在")
            continue
        role=role_dic[choice]
        break

    return username,password2,role


#将账号密码平成固定的格式
def register_interface(username,password,role):
    format_str='%s:%s:%s
'%(username,password,role)
    return format

# 将拼好的密码写成固定的格式


def handle_file(format_str ,filepath):
    with open(r'%s' %filepath,'at',encoding='utf-8') as f:
        f.write(format_str)

def register ():
    user,name,role=talk()
    format_str=register_interface(user,pwd,role)
    handle_file(format_str,'user.txt')

register()
View Code













原文地址:https://www.cnblogs.com/ouyang99-/p/9430454.html