# encoding: utf-8
"""
@author: lanxiaofang
@software: PyCharm
@file: 09_0210_enum_advgram_usage.py
@time: 2020/2/10 12:42
"""

# 枚举
# from enum import Enum
# class VIP(Enum):
# RED = 1
# YELLOW = 2
# BLACK = 3
# GREEN = 4
# print(VIP.YELLOW.value)

# 枚举的特点 不可重复 不可修改
"""
# 方式一:
yellow = 1
green = 2
# 方式二:
dicta = {'yellow': 1, 'green': 2, 'yellow': 3}
print(dicta['yellow'])
# 方式三:
class TypeDiamond():
yellow = 1
green = 2
TypeDiamond.yellow = 3
print(TypeDiamond.yellow)
# 方式四:
from enum import Enum
# class VIP(Enum):
# RED = 1
# # RED = 5 # 不可以有重复:报错: TypeError: Attempted to reuse key: 'RED'
# YELLOW = 2
# BLACK = 3
# GREEN = 4
# VIP.YELLOW.value = 5 # Enum的值不可修改:报错:AttributeError: can't set attribute
# print(type(VIP.YELLOW), VIP.YELLOW, VIP['YELLOW']) # 枚举类型,枚举名字,枚举的值
# print(type(VIP.YELLOW.name), VIP.YELLOW.name)
# print(type(VIP.YELLOW.value), VIP.YELLOW.value)
"""

# from enum import Enum
# class VIP(Enum):
# RED = 1
# YELLOW = 2
# BLACK = 3
# GREEN = 4
# for vip in VIP:
# print(vip)

# from enum import Enum
# class VIP(Enum):
# RED = 1
# YELLOW = 2
# BLACK = 3
# GREEN = 4
# PINK = 1
#
# # result = VIP.YELLOW > VIP.RED # 不能做大小比较 TypeError: '>' not supported between instances of 'VIP' and 'VIP'
# # result = VIP.RED == VIP.PINK # 可以做等值比较
# # result1 = VIP.RED == VIP.BLACK
# # print(result, result1)

# from enum import Enum
# class VIP(Enum):
# RED = 1
# YELLOW = 2
# BLACK = 3
# GREEN = 4
# PINK = 1
# class VIP1(Enum):
# RED = 1
# YELLOW = 2
# BLACK = 3
# GREEN = 4
# PINK = 1
# result = VIP == VIP1
# result1 = VIP.RED == VIP.PINK
# print(result, result1)

# from enum import Enum
# class VIP(Enum):
# RED = 1
# YELLOW = 2
# BLACK = 3
# GREEN = 4
# PINK = 1 # 允许名称不同,值相同:PINK 相当于RED的别名
#
# print(VIP.RED, VIP.PINK) # VIP.RED VIP.RED
# for vip in VIP:
# print(vip) # 不会输出PINK
# print(type(VIP.__members__)) # <class 'mappingproxy'>
# for vip_member in VIP.__members__: # 如果要输出PINK则.__members__
# print(vip_member, type(vip_member))

# IntEnum 作用 枚举类型的值只能是数字
# from enum import IntEnum
# class VIP(IntEnum):
# WHITE = '0'
# #BAISE = '零' # 因为是IntEnum所以只能是数字,报错: ValueError: invalid literal for int() with base 10: '零'
# RED = 1
# YELLOW = 2
# BLACK = 3
# GREEN = 4
# print(VIP.RED)

# unique 不能有 别名(名称不一样,值相同)
# from enum import IntEnum, unique
#
# @unique
# class VIP(IntEnum):
# WHITE = 1
# # RED = 1 # 报错 ValueError: duplicate values found in <enum 'VIP'>: RED -> WHITE
# YELLOW = 2
# BLACK = 3
# GREEN = 4
# print(VIP.WHITE)


# def a():
# pass
# print(type(a)) # <class 'function'>

# 把一个函数当做另外一个函数的返回结果
# def curve_pre():
# def curve():
# print("this is in curve function")
# return curve()
# f = curve_pre()

# 另外一个函数的参数,传递到另外的函数里
# def cur_pre():
# a = 5
# def cur(x):
# return a*x**2
# return cur
# c = cur_pre()
# print(c(2))


# 闭包 = 函数 + 环境变量(定义时的函数中的变量) 闭包保存的是一个函数运行的现场
# def cur_pre():
# a = 5
# def cur(x):
# return a*x**2
# return cur
# c = cur_pre()
# print(type(c.__closure__), c.__closure__)
# print(c.__closure__[0].cell_contents)
# print(c(2))

# def f1():
# a = 10
# def f2():
# a = 20 # 此时a被认为是局部变量,不会影响f1()中的a的值,此时的闭包不存在
# print(a)
# print(a)
# f2()
# print(a)
# f1()

# def f1():
# a = 10
# def f2():
# # a = 20 # 此时a被认为是局部变量,不会影响f1()中的a的值,此时的闭包不存在
# b = a+2 # 只要引用了a 则被认为是闭包
# print(b)
# return f2
# f = f1()
# print(f.__closure__)

# 闭包有什么用
# origin = 0
# def walk(i):
# w = origin + i
# return origin
# print(walk(2))
# print(walk(4))
# print(walk(5))
#
# origin = 0
# def walk(i):
# w = origin + i # 报错 UnboundLocalError: local variable 'origin' referenced before assignment
# origin = w # 当 walk()中有origin时,则不会调用全局变量origin=0,因此会被认为没有被定义就被使用
# return origin
# print(walk(2))
# print(walk(4))
# print(walk(5))
#
#
# 但是我们希望origin记住上一次的值:
# 可以用 global(非闭包的方法)
# origin = 0
# def walk(i):
# global origin
# w = origin + i
# origin = w
# return origin
# print(walk(2))
# print(walk(4))
# print(walk(5))
# 使用闭包的方法
# origin = 0
# def walk(pos):
# def go(step):
# nonlocal pos
# new_pos = pos + step
# pos = new_pos
# return new_pos
# return go
#
# tourist = walk(origin)
# print(tourist(2))
# print(tourist.__closure__[0].cell_contents)
# print(tourist(4))
# print(tourist.__closure__[0].cell_contents)
# print(tourist(6))
# print(tourist.__closure__[0].cell_contents)