type
status
date
slug
summary
tags
category
icon
password
Property
目录
生成器
通过列表生成式,可以直接创建一个列表。但是受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的
list
,从而节省大量的空间。在Python
中,这种一边循环一边计算的机制,称为生成器:generator
。用列表生成式创建
要创建一个
generator
,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]
改成()
,就创建了一个generator
:创建
L
和g
的区别仅在于最外层的[]
和()
,L
是一个list,而g
是一个generator
。type
status
date
slug
summary
tags
category
icon
password
Property
目录
函数作为返回值
高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。实现一个可变参数的求和,通常情况下,求和的函数是这样定义的:
但是,如果不需要立刻求和,而是在后面的代码中,根据需要再计算怎么办?可以不返回求和的结果,而是返回求和的函数:
在函数
lazy_sum
中又定义了函数sum
,并且,内部函数sum
可以引用外部函数lazy_sum
的参数和局部变量,当lazy_sum
返回函数sum
时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。注意一点,当调用
lazy_sum()
时,每次调用都会返回一个新的函数,即使传入相同的参数:type
status
date
slug
summary
tags
category
icon
password
Property
在传入函数时,有些时候不需要显式地定义函数,直接传入匿名函数更方便,
Python
对匿名函数提供了有限支持。以
map()
函数为例,计算 时,除了定义一个f(x)
的函数外,还可以直接传入匿名函数:匿名函数
lambda x: x * x
实际上就是:关键字
lambda
表示匿名函数,冒号前面的x
表示函数参数。匿名函数有个限制,就是只能有一个表达式,不用写
return
,返回值就是该表达式的结果。用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数:
type
status
date
slug
summary
tags
category
icon
password
Property
作用:装饰器的作用就是为已经存在的对象添加额外的功能
本质:本质上是一个
Python
函数或类,可以让其他函数或类在不需要做任何代码修改的前提下增加额外功能应用场景:经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景,可以抽离出大量与函数功能本身无关的雷同代码到装饰器中并继续重用
由于函数也是一个对象,而且函数对象可以被赋值给变量,所以通过变量也能调用该函数:
假设要增强
now()
函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改now()
函数的定义,这种在代码运行期间动态增加功能的方式,称之为装饰器(Decorator)。本质上,
decorator
就是一个返回函数的高阶函数。所以定义一个能打印日志的decorator
,可以如下:type
status
date
slug
summary
tags
category
icon
password
Property
Python
的functools
模块提供了很多有用的功能,其中一个就是偏函数(Partial function),这里的偏函数和数学意义上的偏函数不一样。通过设定函数参数的默认值,可以降低函数调用的难度,偏函数也可以做到这一点:
int()
函数可以把字符串转换为整数,当仅传入字符串时,int()
函数默认按十进制转换:int
('12345')
但
int()
函数还提供额外的base
参数,默认值为10
。如果传入base
参数,就可以做N进制的转换:假设要转换大量的二进制字符串,每次都传入
int(x, base=2)
非常麻烦,可以定义一个int2()
的函数,默认把base=2
传进去:functools.partial
就是帮助我们创建一个偏函数的,不需要自己定义int2()
,可以直接创建一个新的函数int2
:type
status
date
slug
summary
tags
category
icon
password
Property
目录
访问限制
在
Class
内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样就隐藏了内部的复杂逻辑。但是从前面Student类的定义来看,外部代码还是可以自由地修改一个实例的
name
、score
属性:如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线
__
,实例的变量名如果以__
开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问:这样就确保了外部代码不能随意修改对象内部的状态,这样通过访问限制的保护,代码更加健壮。