专栏首页公众号:googpyPython的高级语法与用法(二)

Python的高级语法与用法(二)

(一)枚举转换

例1

给定一个变量a=1,将它转换成枚举类型。根据要求,代码如下:

from enum import Enum

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

class Common():
    YELLOW = 1

a =1
print(VIP(a))
VIP.YELLOW

这种将数字转换成枚举类型的方法和字符串整形转换是不一样的,前者是数值访问具体枚举类型的方案,后者则是数据结构的内部转换。

还需要注意的是,如果给定的变量值不在枚举类,则会报错。

(二)Enum和IntEnum

枚举中不仅有Enum模块,还有IntEnum,那两者在用法上有什么区别呢?

Enum不会对类下面的变量整形限制

from enum import Enum
class VIP(Enum):
    YELLOW = 1
    GREEN  = 'str'
    BLACK  = 3
    RED    = 4

运行不会出错。

IntEnum对于这种情况,则会报错

from enum import IntEnum
class VIP(IntEnum):
    YELLOW = 1
    GREEN  = 'str'
    BLACK  = 3
    RED    = 4
ValueError: invalid literal for int() with base 10: 'str'

上一节的学习可以知道,枚举对于值相等的标签,不会报错,而是把其中一个称为另一个的别名,但是如果需要Python报错,或者限制这种情况,可以按下面这种方法实现之:

from enum import IntEnum,unique

@unique
class VIP(IntEnum):
    YELLOW = 1
    GREEN  = 1
    BLACK  = 3

在引入语法中加入unique,同时在类前面加入@unique这个装饰器,故而运行结果为:

ValueError: duplicate values found in <enum 'VIP'>: GREEN -> YELLOW

(三)闭包

例2

def curve_pre():
    a = 25
    def curve(x):
        return a*x*x
    return curve

f = curve_pre()
print(f(2))
100

说一下我的浅显认识,要形成闭包,首先得有一个嵌套函数,即函数中定义了另一个函数,闭包则是一个集合,它包括了外部函数的局部变量,这些局部变量在外部函数返回后继续存在,并能被内部函数引用。

当对上面代码进行改动时,即加入a=10,打印的结果却不会发生变化,其实这里很好理解,在嵌套函数中,变量a是一个全局变量,通过前面的学习,Python内部的寻找机制,会先寻找本层的局部变量,如果没有则会向上寻找全部变量。

总结,通过一个简单的例子,可以知道闭包由函数和定义时外部环境构成的整体。

(四)__closure__属性和cell对象

def curve_pre():
    a = 25
    def curve(x):
        return a*x*x
    return curve

f = curve_pre()
print(f.__closure__)                    #函数的属性
print(f.__closure__[0].cell_contents)   #定义时的环境变量
print(f(2))                             #函数返回值
(<cell at 0x000000000265F768: int object at 0x000007FEDDD9E650>,)
25
100

Python中函数也是对象,所以函数也有很多属性,和闭包相关的就是__closure__属性,如果函数是一个闭包,则它返回的是一个由cell对象组成的元组对象。Cell对象的cell_contents属性就是闭包的自由变量(全局变量)

(五)一个关于闭包的例子

(1)先看一下三个打印值分别会返回多少?

def f1():
    a =10
    def f2():
        a =20
        print(a)    #第二次
    print(a)        #第一次
    f2()
    print(a)        #第三次

f1()
10
20
10

分析代码运行的过程,由外及里。在代码中我把每个打印值出现的次数也标了出来,方便大家理解。

(2)再看下面这段代码是闭包吗?

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

f = f1()
print(f)
print(f.__closure__)
<function f1.<locals>.f2 at 0x00000000021E89D8>
None

我们删去上面代码中的打印语句,再加入return,看看代码运行结果。检验函数是否为闭包,需要用到.__closure__属性。

(3)再将上述代码进行修改,删掉f2中的变量a,结果为

<function f1.<locals>.f2 at 0x00000000021D89D8>
(<cell at 0x000000000216F768: int object at 0x000007FEDE16E470>,)

可以看到此时是闭包

(4)如果在f2函数中加入一个c=20*a,那么结果又如如何呢?

def f1():
    a =10
    def f2():
        c = 20 * a
    f2()
    return f2

f = f1()
print(f)
print(f.__closure__)
<function f1.<locals>.f2 at 0x00000000021D89D8>
(<cell at 0x000000000216F768: int object at 0x000007FEDDD9E470>,)

总结

(1)闭包避免了使用全局变量,此外,闭包允许将函数与其操作的某些数据(环境)关联起来。

(2)局部变量最好不要与环境变量同名,否则就不是一个闭包;

(3)闭包的意义是,保存环境变量,即将函数调用时的“现场”保存下来。

本文分享自微信公众号 - googpy(googpy),作者:stormwen

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-05-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 常见的Python面试题

    花了两天时间,整理了一些常见的Python面试题,希望对即将参加招聘面试的或者准备转行的同学有一些帮助,临阵磨枪不快也光,大家加油鸭!

    stormwen
  • python的迭代对象

    迭代对象这个概念是python里面非常核心的东西,我想跟大家分享一下,什么是可迭代对象。

    stormwen
  • 清清爽爽理解Python装饰器

    不知不觉已经连续写了13天了,很享受每天写公众号这个过程,通过写作将自己每天学习的Python知识分享出来,但是学习的东西是零散的,需要自己通过一定的逻辑顺序将...

    stormwen
  • Python|关于def函数

    在我们想要用代码来解决问题时,可能某一种关系会多次用到,但是复制粘贴有违反了软件工程中的DRY原则,python为我们提供了函数功能,我们可以通过引用内置函数或...

    算法与编程之美
  • 在ubuntu上玩flatpak打包的游戏

    flatpak是一个个打包方式,为的是可以在不同的linux发行版本上运行同一个版本的应用,具体的大家可以深入研究。下面我就带领大家在ubuntu上运行用fla...

    bboysoul
  • Caffe学习系列(6):Blob,Layer and Net以及对应配置文件的编写

    http://www.cnblogs.com/denny402/p/5073427.html

    bear_fish
  • 新主题博客诞生之路

    卡少
  • 4️⃣ 核酸序列特征分析(2):CpG岛预测

    CpG岛是200bp或更长的DNA序列,GC含量较高,一般富集在人类基因组组启动子区和起始外显子去,在这个区段容易出现DNA甲基化,从而对基因表达进行调控。 ...

    Y大宽
  • [Leetcode][python]Text Justification/文本左右对齐

    来自:https://shenjie1993.gitbooks.io/leetcode-python/068%20Text%20Justification.ht...

    后端技术漫谈
  • windows 多任务与进程

    多任务的本质就是并行计算,它能够利用至少2处理器相互协调,同时计算同一个任务的不同部分,从而提高求解速度,或者求解单机无法求解的大规模问题。以前的分布式计算正是...

    Masimaro

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动