美文网首页
10.python的高级语法与用法、闭包

10.python的高级语法与用法、闭包

作者: tomtiddler | 来源:发表于2018-10-01 09:23 被阅读0次

枚举其实是一个类

from enum import Enum

class VIP(Enum):
    YELLOW = 1
    GREEN = 2
    BLACK = 3
    RED = 4

print(VIP.YELLOW)  # -> VIP.YELLOW

枚举的意义是其名字 而不是其数值

枚举类和普通类相比有什么优势

表示一连串类型的方法:
1.普通的类和字典第一个缺陷是,没有防止改变的机制。
2.没有防止相同标签的功能

枚举类型、枚举名称与枚举值:

通过type函数查看

print(type(VIP.GREEN.name))  # 枚举的名字
print(type(VIP.GREEN))  # 枚举的类
print(type(VIP["GREEN"])) # 枚举的类

枚举类可以遍历
廖雪峰--枚举类

枚举的比较运算

result = VIP.GREEN
assert result != VIP.BLACK, "false"
assert result is VIP.GREEN, "false"

枚举可以进行相等与不等比较,不能进行大小比较。
可以 is 比较。身份比较
对于不同的枚举类,即使名字和值一样,也不相等。属于不同类

枚举注意事项

1.枚举下不能有相同的标签
2.枚举下可以有相同的值,那么第一个类型之后的相同值的名字是第一个类型的别名!!!枚举类有装饰器@unique检查保证不重复(相同值)

from enum import Enum # unique

# @unique
class VIP(Enum):
    YELLOW = 1
    GREEN = 2
    BLACK = 2
    RED = 4

print(VIP.YELLOW)
print(type(VIP.GREEN.name))
print(type(VIP.GREEN))
print(type(VIP["GREEN"]))

result = VIP.GREEN
assert result == VIP.BLACK, "false"  # 由于重复的赋值,导致两个成员值相等,并且调用BLACK返回的名字会是GREEN
assert result is VIP.GREEN, "false"

for v in VIP:  # 没有BLACK
    print(v)

for v in VIP.__members__:  # 有BLACK
    print(v)

很有意思,感觉有一定的实用价值。

枚举转换

推荐存储类型的方法:存储数字,采用枚举类来解析所存储的数字。能增加代码的可读性。
通过数字读取枚举类的方法 -> print(VIP(1))

枚举小结:

Enum值可以是字符串,如果需要强制是整数,需要用到IntEnum
枚举类用装饰器@unique检查保证不重复(相同值?)
采用的是单例模式,所以无法实例化 -> 猜到了
23种设计模式

进阶内容开场白

高阶知识用在编程哪些方面:
包、类库的开发者。

一切皆对象

函数式编程
如果用类写代码写的很繁琐,别扭,就可以考虑函数式编程
闭包的概念
廖雪峰--闭包--封装
可以把一个函数作为另一个函数的参数传递进去
也可以把一个函数作为另一个函数的返回结果。
个人认识:主要看一个函数的运行结果是关于函数的引用还是关于函数的调用。

什么是闭包

个人认识:就是初次运行函数并不返回运行值,而是返回一个可调用的对象,在此调用就会返回运行值。

# 最简单的闭包
# 返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
def curve_pre():
    a = 25
    
    def curve(x):
        y = a * x ^ 2 + x
        return y
    return curve


re = curve_pre()
print(re)  # <function curve_pre.<locals>.curve at 0x7f73b9e27158>
print(re.__closure__)  # 闭包的参数对象
print(re.__closure__[0].cell_contents)  # 返回闭包的参数
print(re(2))

闭包需要调用到函数的局部变量,否则闭包意义不大。
返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

一个事例看闭包

闭包 = 函数 + 环境的变量(局部变量)
闭包的意义:保存的是一个环境 -> 不可调用后续发生变化的值。(最好是调用局部变量)
需要注意的地方:

def f1():
    a = 10
    def f2():
        a = 20
        print(a)
    print(a)
    f2()
    print(a)

f1() # 返回 10  20  10

闭包的经典误区

def f1():
    a = 10
    def f2():
        a = 20  # 闭包内部不能定义局部变量 可以采用 a = a + 10 的方式引用外部变量
        return a
    return f2

f = f1()
print(f)
print(f.__closure__)  # 返回None,一旦函数的内部定义赋值了局部变量,将不再形成闭包,必须引用外部变量!!!

出个题,用闭包解决

我先用非闭包解决一下

origin = 0

def go(step):
    global origin
    new_pos = origin + step
    origin = new_pos
    return origin

print(go(2))
print(go(3))
print(go(6))

再用闭包解决一下

origin = 0

def factory(pos):

    def move(step):
        nonlocal pos
        new_pos = pos + step
        pos = new_pos
        return new_pos

    return move

f = factory(origin)

print(f(2))
print(f(3))
print(f(8))

自封闭性,没有取改变全局变量的值。而是自己保存上次执行完成之后的环境的变量,将变量的改变局限在函数内部。
闭包
如果用类,类变量就能解决此问题。

小谈函数式编程

factory : 工厂模式
python的闭包强调的是保存环境变量
javascript的闭包强调的是函数外部访问函数内部的变量
由于闭包产生的函数以及变量是常驻内存,容易导致内存泄漏。

相关文章

  • 10.python的高级语法与用法、闭包

    枚举其实是一个类 枚举的意义是其名字 而不是其数值 枚举类和普通类相比有什么优势 表示一连串类型的方法:1.普通的...

  • python高级之闭包

    python高级之闭包 什么是闭包? 闭包(closure)是函数式编程的重要的语法结构。闭包也是一种组织代码的结...

  • Python 2 - 高级用法 - 装饰器

    Python 2 - 高级用法 - 装饰器 一谈到 装饰器,就离不开闭包 闭包 闭包就是能够读取其他函数内部变量的...

  • 闭包-Closures [swift 5.1]

    闭包的语法 尾随闭包 闭包逃离 自动闭包

  • python函数部分

    什么是闭包,闭包的常用用法,怎样判断是不是闭包,闭包的作用是 1、什么是闭包 2、常用用法 3、判断是不是闭包 4...

  • 『iOS语法』闭包语法与实战

    『iOS语法』闭包语法与实战 闭包这种语法,其实很多语言都在用,学过Android的朋友,一定发现,在gradle...

  • Swift 2 学习笔记 9.闭包

    课程来自慕课网liuyubobobo老师 闭包 闭包的基本语法 闭包语法的简化 结尾闭包 内容捕获 闭包和函数是引用类型

  • Swift4.2基础学习笔记(十)

    参考资料与链接https://www.cnswift.org 闭包表达式 Sorted方法 闭包表达式语法 闭包表...

  • 闭包

    闭包的基本语法 闭包的内容捕获 闭包和函数的引用类型

  • Swift~ @escaping @noescaping 逃逸

    闭包表达式语法 闭包表达式语法有如下的一般形式: 闭包只有在函数中做参数时,才会区分逃逸闭包和非逃逸闭包 Swif...

网友评论

      本文标题:10.python的高级语法与用法、闭包

      本文链接:https://www.haomeiwen.com/subject/vwxnnftx.html