• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

竹千代

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

语言特性

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/

 

posted on 2015-04-27 17:30  竹千代  阅读(232)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3