一、python基础部分
二、python进阶部分
1、
In [20]: [lambda x, i=2 : i * x for x in [1,2,3,4]]
Out[20]:
[<function __main__.<listcomp>.<lambda>>,
<function __main__.<listcomp>.<lambda>>,
<function __main__.<listcomp>.<lambda>>,
<function __main__.<listcomp>.<lambda>>]
如下方式执行for循环的是4个函数,其实lambda并没有执行,应该修改为如下:
In [3]: aa = lambda x, i=2 : i * x
In [4]: [aa(x) for x in [1,2,3,4]]
Out[4]: [2, 4, 6, 8]
2、Python闭包错误
In [7]: def muls():
...: return [lambda x : i * x for i in range(4)]
...:
...:
In [8]: [m(2) for m in muls()]
Out[8]: [6, 6, 6, 6]
如上结果返回的是6,6,6,6 而不是0,2,4,6
原因:
(1)形成闭包的条件
http://www.iaskjob.com/admin/zinnia/entry/232/?_changelist_filters=q%3D%25E9%2597%25AD%25E5%258C%2585
(2)原因是闭包函数引用了外部的变量,导致出现使用了外部完成循环后的数值
类似如下:
In [14]: def muls3():
...: alist = []
...: for i in range(4):
...: def aa(x,key=i):
...: return i*x
...: alist.append(aa)
...: return alist
...:
In [15]: [m(2) for m in muls3()]
Out[15]: [6, 6, 6, 6]
return i*x ,i是外部的变量的,所以这个时候就触发了问题
In [12]: def muls2():
...: alist = []
...: for i in range(4):
...: def aa(x,key=i):
...: return key*x
...: alist.append(aa)
...: return alist
...:
In [13]: [m(2) for m in muls2()]
Out[13]: [0, 2, 4, 6]
return i*x 修改为key*x,成为内部变量,这个时候完成正常循环
3、单例模式的实现
单例模式模式的出现为了解决相同类被多次实例化后,导致严重的内存资源浪费。
默认,我们看下一个类的调用:
In [16]: class Myclass():
...: a = 1
...:
In [17]: a = Myclass()
In [18]: b = Myclass()
In [19]: id(a)
Out[19]: 4361723056
In [20]: id(b)
Out[20]: 4361726288
In [21]: a is b
实现单例模式调用,可以通过几种写法来实现:
第一种、使用__new__来控制
我们将类的实例和一个类变量 _instance 关联起来,如果 cls._instance 为 None 则创建实例,否则直接返回 cls._instance。
In [22]: class SingleClass(object):
...: _instance = None
...: def __new__(cls,*args,**kw):
...: if not cls._instance:
...: cls._instance = super(SingleClass,cls).__new__(cls,*args,**kw)
...: return cls._instance
...:
In [23]: class Myclass(SingleClass):
...: a = 1
...:
In [24]: a = Myclass()
In [25]: b = Myclass()
In [28]: id(a)
Out[28]: 4364931856
In [29]: id(b)
Out[29]: 4364931856
In [30]: a is b
Out[30]: True
第二种、使用元类实现
元类(metaclass)可以控制类的创建过程,它主要做三件事:
- 拦截类的创建
- 修改类的定义
- 返回修改后的类
In [31]: class Singleton(type):
...: _instances = {}
...: def __call__(cls, *args, **kwargs):
...: if cls not in cls._instances:
...: cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
...: return cls._instances[cls]
...:
...: # Python2
...: class MyClass(object):
...: __metaclass__ = Singleton
...:
In [32]:
In [32]: a = MyClass()
In [33]: b = MyClass()
In [34]: a is b
Out[34]: True
第三种,使用装饰器的方式
定义了一个装饰器 singleton
,它返回了一个内部函数 getinstance
,该函数会判断某个类是否在字典 instances
中,如果不存在,则会将 cls
作为 key,cls(*args, **kw)
作为 value 存到 instances
中,否则,直接返回 instances[cls]
。
In [40]: from functools import wraps
...:
...: def singleton(cls):
...: instances = {}
...: @wraps(cls)
...: def getinstance(*args, **kw):
...: if cls not in instances:
...: instances[cls] = cls(*args, **kw)
...: return instances[cls]
...: return getinstance
...:
...: @singleton
...: class MyClass(object):
...: a = 1
...:
In [41]: a = MyClass()
In [42]: b = MyClass()
In [43]: a is b
Out[43]: True