11Python的高级语法和用法

11-1 枚举其实是一个类

# 11-1 枚举其实是一个类
# 类型
绿钻 、黄钻、 红钻、 黑钻
1 绿钻
2 黄钻
3 红钻
4 黑钻
# 字典不是最优的表示方法。下面看看枚举可以表示各种各样的类型!

from enum import Enum

class VIP(Enum):#继承Python给我们提供的enum类
    YELLOW = 1
    GREEN = 2
    BLACK = 3            #枚举的标识名字大写
    RED = 4
print(VIP.YELLOW)
# 打印结果如图1,不是1!!!这就是枚举的意义重点在于标识标签不是数字

image

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

# 11-2 枚举和普通类相比有什么优势

# 第一种形式类变量
yellow = 1
green = 2

# 第二种字典形式 :
{'yellow':1,'green':2}

# 第三种形式 用类
class TypeDiamond():
    yellow = 1
    green = 2

# 以上三种形式都有一个共同的缺陷:第一就是可变,第二,没有防止相同值得功能(比如不同的标签出现相同标签的功能)

11-3 枚举类型、枚举名称与枚举值

# 11-3 枚举类型、枚举名称与枚举值

# Q1:如何获得每一个标签下面所对应的数值
from enum import Enum

class VIP(Enum):
    YELLOW = 1
    BLACK = 3           
    RED = 4
# 别名
class common():
    YELLOE = 1
print(VIP.YELLOW.value)#通过点value的形式打印标签的对应值
# 打印结果如图1 

# Q2:如何获得每一个值下面所对应的标签
from enum import Enum

class VIP(Enum):
    YELLOW = 1
    BLACK = 3           
    RED = 4
# 别名
class common():
    YELLOE = 1
print(VIP.YELLOW.name)#通过点name的形式打印数值对应的标签
# 打印结果如图2

# 看看下面的打印类型
from enum import Enum

class VIP(Enum):
    YELLOW = 1
    BLACK = 3           
    RED = 4
# 别名
class common():
    YELLOE = 1
print(type(VIP.YELLOW.name))#看看这两个的不同
print(type(VIP.YELLOW))
print(VIP['RED'])
#打印结果如图3和图5,第一个是字符串类型,第二个是枚举类型
# 枚举类型(通过名称可以获得枚举类型)、枚举的值(1,2,3,4)、枚举的名字(标签的名字)

# 枚举是可以用来遍历的
from enum import Enum

class VIP(Enum):
    YELLOW = 1
    BLACK = 3           
    RED = 4
# 别名
class common():
    YELLOE = 1

for v in VIP:#for循环的遍历
    print(v)
    #打印结果如图4

image
image
image
image
image

11-4 枚举的比较运算

# 11-4 枚举的比较运算

from enum import Enum

class VIP(Enum):
    YELLOW = 1
    GREEN = 2
    BLACK = 3           
    RED = 4
# 别名
class common():
    YELLOE = 1
result = VIP.GREEN == VIP.BLACK
print(result)

# 打印结果如图1

from enum import Enum

class VIP(Enum):
    YELLOW = 1
    GREEN = 2
    BLACK = 3           
    RED = 4
# 别名
class common():
    YELLOE = 1
result = VIP.GREEN > VIP.BLACK#枚举不支持大小比较
print(result)

# 打印结果如图2

from enum import Enum

class VIP(Enum):
    YELLOW = 1
    GREEN = 2
    BLACK = 3           
    RED = 4
# 别名
class common():
    YELLOE = 1
# result = VIP.GREEN > VIP.BLACK
result = VIP.GREEN is VIP.GREEN
print(result)
# 打印结果如图3

from enum import Enum

class VIP(Enum):
    YELLOW = 1
    GREEN = 2
    BLACK = 3           
    RED = 4
class VIP1(Enum):
    YELLOW = 1
    GREEN = 2
    BLACK = 3           
    RED = 4
# 别名
class common():
    YELLOE = 1

result = VIP.GREEN == VIP1.GREEN
print(result)
# 打印结果如图4,打印的结果是false,虽然数值相同,但是不是同一个枚举

image
image
image
image

11-5 枚举注意事项

# 11-5 枚举注意事项

from enum import Enum

class VIP(Enum):
    YELLOW = 1
    GREEN = 1#如果两个数值一样,打印的结果会是什么?
    BLACK = 3           
    RED = 4

# 别名
class common():
    YELLOE = 1

print(VIP.GREEN)
# 打印结果如图1,并不会报错,只是会打印出来YELLOW,原因如下:
from enum import Enum

class VIP(Enum):
    YELLOW = 1
    YELLOW_ALIAS = 1#如果两个数值一样,第二个GREEN,将成为第一个YELLOW的别名!!附属
    BLACK = 3           
    RED = 4
class common():
    YELLOE = 1
print(VIP.GREEN)

# 看看遍历下面的注意事项
from enum import Enum
class VIP(Enum):
    YELLOW = 1
    YELLOW_ALIAS = 1#如果两个数值一样,第二个GREEN,将成为第一个YELLOW的别名!!附属
    BLACK = 3           
    RED = 4
class common():
    YELLOE = 1
for v in VIP:
    print(v)
# 打印结果如图2所示,只打印了3个,别名是不会打印出来的

# 那么如果想要打印出来别名怎么办?
from enum import Enum
class VIP(Enum):
    YELLOW = 1
    YELLOW_ALIAS = 1
    BLACK = 3           
    RED = 4
class common():
    YELLOE = 1
for v in VIP.__members__.items():#内置__members__变量属性下面的items方法
    print(v)
# 打印结果如图3所示,只打印了4个,别名是会打印出来的

# (还有一种方法)那么如果想要打印出来别名怎么办?
from enum import Enum
class VIP(Enum):
    YELLOW = 1
    YELLOW_ALIAS = 1
    BLACK = 3           
    RED = 4
class common():
    YELLOE = 1
for v in VIP.__members__:#直接使用内置__members__变量属性即可
    print(v)
# 打印结果如图4所示,只打印了4个,别名是会打印出来的

image
image
image
image

11-6 枚举转换

# 在数据库中建议使用数字的形式来存储,省内存还方便(数字的形式来代表类型)

# 下面看看在代码里使用数字来代表枚举类型
from enum import Enum
class VIP(Enum):
    YELLOW = 1
    YELLOW_ALIAS = 1
    BLACK = 3           
    RED = 4
class common():
    YELLOE = 1
if a==1:         #这种形式的代码可读性不是很强
    print()
if a==2:
    print()
for v in VIP.__members__:#直接使用内置__members__变量属性即可
    print(v)

    # 看看这种可读性强一点的代码
from enum import Enum
class VIP(Enum):
    YELLOW = 1
    YELLOW_ALIAS = 1
    BLACK = 3           
    RED = 4
class common():
    YELLOE = 1
if a==VIP.YELLOW:         #这种形式的代码可读性很强
    print()
if a==VIP.BLACK:
    print()
for v in VIP.__members__:#直接使用内置__members__变量属性即可
    print(v)

# 如何把数字转换成枚举类型?
from enum import Enum
class VIP(Enum):
    YELLOW = 1
    YELLOW_ALIAS = 1
    BLACK = 3           
    RED = 4
class common():
    YELLOE = 1
a = 1       #通过这种方式就可以进行转换了,使用具体的数值来访问枚举类型的方案
print(VIP(a))

# 打印结果如图1

image

11-7 枚举小结

# 11-7 枚举小结

from enum import Enum
from enum import IntEnum
class VIP(IntEnum):
    YELLOW = 1
    GREEN = 'str'  #如果枚举类型下面都是数字类型,不允许出现字符串。可以使用IntEnum
    BLACK = 3           
    RED = 4

# 如果出现相同的数值怎么办?
from enum import Enum
from enum import IntEnum,unique

@unique
class VIP(IntEnum):
    YELLOW = 1
    GREEN = 1  #如果出现两个相同的数字,我们不希望出现别名,希望他报错,那么可以采用@unique(装饰器)
    BLACK = 3           
    RED = 4
# 打印结果如图1

# 23种设计模式,枚举是单例模式,在Python中不要实例化

image

11-8 进阶内容开场白

1.业务逻辑的开发者,不考虑太多的封装性
2.包、类的开发者
11-9 一切皆对象

# 11-9 一切皆对象
# 函数式编程(淡化这个概念)
# 闭包的概念

# 学习函数,是为了上面两个
# 函数只是一段可以执行的代码,并不是对象。不能实例化,而对象可以实例化
# Python里一切都是对象
# 在Python里,另外一个函数的参数,传递到另外的函数里
# 在Python里,把一个函数当做另外一个函数的返回结果

def a():
    pass
print(type(a))

# 打印结果如图1,是一个类

image

11-10 什么是闭包

# 11-10 什么是闭包
def curve_pre():#抛物线函数
    def curve():
        pass

curve()#这时候调用curve不可以,因为它在函数里面,属于内部函数

# 打印结果如图1

def curve_pre():
    def curve():
        print('this is a function')
        pass
    return curve #这个肯定可以返回,函数作为一个返回结果,被另一个函数给返回回来的

f = curve_pre()#可以把函数赋值给另外一个变量!!
f()

# 打印结果如图2

def curve_pre():
    a = 25
    def curve(x):
        return a*x*x
    return curve #这个肯定可以返回,函数作为一个返回结果,被另一个函数给返回回来的

f = curve_pre()#可以把函数赋值给另外一个变量!!
print(f(2))

# 打印结果如图3

# 看看下面的执行结果,结果是多少?
def curve_pre():
    a = 25
    def curve(x):
        return a*x*x
    return curve 
a = 10
f = curve_pre()#
print(f.__closure__)#闭包的结果存放的地方
print(f.__closure__[0].cell_contents)

# 此时f(2) = curve_pre()
print(f(2))

# 打印结果如图4,为什么结果是100不是40?
# 闭包 = 函数+环境变量

# 闭包和全局变量是有区别的!!
a = 25   #全局变量
def curve_pre():
    def curve(x):
        return a*x*x
    return curve 
a = 10
f = curve_pre()#可以把函数赋值给另外一个变量!!
# 此时f(2) = curve_pre()
print(f(2))
# 打印结果如图5

image
image
image
image
image

11-11 一个事例看看闭包

11-12 闭包的经典误区
# 11-11 一个事例看看闭包
# 11-12 闭包的经典误区


# 闭包 = 函数+环境变量(定义时候的变量)
# 不仅有返回值,而且还有现场
def curve_pre():
    a = 25
    def curve(x):
        return a*x*x
    return curve 
a = 10
f = curve_pre()
print(f.__closure__)#闭包的结果存放的地方
print(f.__closure__[0].cell_contents)


print(f(2))

# 看看下面代码,理解意义
def f1():
    a = 10
    def f2():
        # 此时将被Python认为是一个局部变量
        a = 20
        print(a)
    print(a)
    f2()
    print(a)
f1()
# 打印结果如图1,上述代码执行的时候,一定是由外到里。想想打印结果!!!
# 看看下面的闭包的形式!!!
def f1():
    a = 10
    def f2():
        # 此时将被Python认为是一个局部变量
        a = 20
        return a
    return f2
f = f1()
print(f)
f1(f.__closure__)
# 这种情况不属于闭包,a = 20,并没有引用外部变量。所以不是闭包只是会被当成局部变量。
# 第二个函数里的a,一定要去引用,不能去赋值。否则就不是闭包

11-13 出个题,用闭包解决!

11-14 先用非闭包的方法解决
11-15 再用闭包解决一下_

# 11-13 出个题,用闭包解决!
# 11-14 我先用非闭包解决一下
# 11-15 再用闭包解决一下_

# 计算旅行者所走的步数
origin = 0

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

print(go(2))
print(go(3))
print(go(6))
# 上述过程是错误的,结果会报错。将origin = new_pos注释掉,打印的结果,全部是0。想想这个结果为什么不行,错在哪里?

# 怎么改写?会有正确的结果
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))
# 打印结果如图1.正确的结果

# 11-15 再用闭包解决一下_
origin = 0
def factory(pos):
    def go(step):
        nonlocal  pos#声明一下,不是局部变量用nonlocal
        new_pos = pos + step 
        pos = new_pos 
        return new_pos
    return go

tourist = factory(origin)
print(tourist(2))
print(tourist.__closure__[0].cell_contents)#打印看看是不是闭包在起作用
print(tourist(3))
print(tourist.__closure__[0].cell_contents)
print(tourist(6))
print(tourist.__closure__[0].cell_contents)

image

作者:buaishengqi
链接:https://www.jianshu.com/p/5dd0601d105c
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,219评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,363评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,933评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,020评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,400评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,640评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,896评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,597评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,327评论 1 244
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,581评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,072评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,399评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,054评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,849评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,672评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,585评论 2 270

推荐阅读更多精彩内容