语言特性
1、魔方函数
http://www.rafekettler.com/magicmethods.html
2、with关键句
class Excutor: def __enter__(self): set things up return thing def __exit__(self, type, value, traceback): tear things down with Excutor() as thing: some code
自动进行开工准备和结束收尾工作
Excutor()执行的结果是返回一个已经实现__enter__、__exit__函数的对象
3、迭代器与生成器
class yrange: def __init__(self, n): self.i = 0 self.n = n def __iter__(self): return self def next(self): if self.i < self.n: i = self.i self.i += 1 return i else: raise StopIteration()
迭代对象可以用于:
- for x in iterator
- sum, list以及itertool包中的函数
实现了__iter__函数,并且__iter__函数返回值可以执行next函数,且next出异常时抛出StopIteration
>>> def foo(): ... print "begin" ... for i in range(3): ... print "before yield", i ... yield i ... print "after yield", i ... print "end" ... >>> f = foo() >>> f.next() begin before yield 0 0 >>> f.next() after yield 0 before yield 1 1 >>> f.next() after yield 1 before yield 2 2 >>> f.next() after yield 2 end Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration >>>
生成器是通过函数形式自制可迭代对象,从而达到返回一系列值的目的
4、元类metaclass
不懂
5、动态创建类
方法一:
>>> def choose_class(name): … if name == 'foo': … class Foo(object): … pass … return Foo # 返回的是类,不是类的实例 … else: … class Bar(object): … pass … return Bar … >>> MyClass = choose_class('foo') >>> print MyClass # 函数返回的是类,不是类的实例 <class '__main__'.Foo> >>> print MyClass() # 你可以通过这个类创建类实例,也就是对象 <__main__.Foo object at 0x89c6d4c>
方法二:
type 接受一个字典来为类定义属性,因此 >>> class Foo(A): … bar = True 可以翻译为: >>> Foo = type('Foo', (A,), {'bar':True})
方法三: 元类
6、descriptor
@locked_cached_property def name(self): if self.import_name == '__main__': fn = getattr(sys.modules['__main__'], '__file__', None) if fn is None: return '__main__' return os.path.splitext(os.path.basename(fn))[0] return self.import_name
class locked_cached_property(object): def __init__(self, func, name=None, doc=None): self.__name__ = name or func.__name__ self.__module__ = func.__module__ self.__doc__ = doc or func.__doc__ self.func = func self.lock = RLock() def __get__(self, obj, type=None): if obj is None: return self with self.lock: value = obj.__dict__.get(self.__name__, _missing) if value is _missing: value = self.func(obj) obj.__dict__[self.__name__] = value return value
通过把类属性构造成特殊类的对象,可以自定义类对象访问属性时的过程
比如,property、classmethod就是标准库中已经实现的descriptor
https://docs.python.org/2/howto/descriptor.html
7、GIL(全局解释器锁)
>>> a = 1
>>> b = 1
>>> id(a) == id(b)
True
>>>
python中,变量都是对象的引用。如上所示,内存中有对象1,a\b分别是它的引用。
--obj.ref_count if(obj.ref_count == 0) destroy obj
当对象的引用数减为0,回收对象所用的内存。
如果是多线程情况,假如线程A执行完if,正准备要执行destroy,此时发生线程调度;而且调度后的线程B,执行if后并执行destroy;等再次调度,线程A恢复执行destroy,那么灾难就发生了。
为解决上述问题,python采用了GIL,就只允许有1个线程使用python解释器,其他线程等待。GIL锁的粒度大,即使有多核,由于其他线程没有python解释器使用权,所以也是空等。同一时刻,1个进程内最多只有1个线程既有CPU,又有Python解释器,从而可以执行。
正是由于GIL,所以python无法发挥多线程的特点。
何时使用python多线程?
代码是IO密集型,多线程可以明显提高效率。例如制作爬虫,绝大多数时间爬虫是在等待socket返回数据。这个时候C代码里是有release GIL的,最终结果是某个线程等待IO的时候其他线程可以继续执行;反之,如果代码是CPU密集型,用多线程效率还不如单线程。
如果你不知道你的代码到底算CPU密集型还是IO密集型,查看 http://www.zhihu.com/question/23474039
8、用C扩展
python执行效率低,所以运行瓶颈的模块部分,可以用C去编写。
https://www.ibm.com/developerworks/cn/linux/l-pythc/