首頁 > 後端開發 > Python教學 > Python 有什么奇技淫巧?

Python 有什么奇技淫巧?

WBOY
發布: 2016-06-06 16:22:10
原創
1178 人瀏覽過

0.这个问题虽说是找寻“奇技淫巧”,但其实是想抛砖引玉
1.如果想把自己认为或好玩或强大的python使用技巧拿出来跟大家分享,可否稍微详细的讲解一下

回复内容:

从 Python 2.3 开始,sys 包有一个属性,叫 meta_path 。可以通过给 sys.meta_path 注册一个 finder 对象,改变 import 的行为。甚至可以实现这样的功能:通过 import 来导入一个 json 文件中的数据。

举个例子,有一个 tester.json 文件,里面的内容是:
<code class="language-text">{
    "hello": "world",
    "this": {
        "can": {
            "be": "nested"
        }
    }
}
</code>
登入後複製
更新一个最近发现的技巧,一行代码实现多线程/多进程,来源于python开发者微信公众号。

首先来看下代码:


import urllib2
from multiprocessing.dummy import Pool as ThreadPool

urls = [
'http://www.python.org',
'http://www.python.org/about/',
'http://www.onlamp.com/pub/a/python/2003
]

pool = ThreadPool(4)
results = pool.map(urllib2.urlopen, urls)
pool.close()
pool.join()

对,你没有看错,只要一行代码就可以把普通的任务变成并行任务。不用手动管理线程,一切都由map自动完成。这里演示的是多线程,如果要多进程的话只需把 from multiprocessing.dummy 改成 from multiprocessing ,就是这么任性!

以下为这个库的详细介绍:

在 Python 中有个两个库包含了 map 函数: multiprocessing 和它鲜为人知的子库 multiprocessing.dummy.

这里多扯两句: multiprocessing.dummy? mltiprocessing 库的线程版克隆?这是虾米?即便在 multiprocessing 库的官方文档里关于这一子库也只有一句相关描述。而这句描述译成人话基本就是说:”嘛,有这么个东西,你知道就成.”相信我,这个库被严重低估了!

dummy 是 multiprocessing 模块的完整克隆,唯一的不同在于 multiprocessing 作用于进程,而 dummy 模块作用于线程(因此也包括了 Python 所有常见的多线程限制)。
所以替换使用这两个库异常容易。你可以针对 IO 密集型任务和 CPU 密集型任务来选择不同的库。


原文链接 : http://mp.weixin.qq.com/s?__biz=MzA4MjEyNTA5Mw==&mid=2652563685&idx=2&sn=f563f8913630a4334219ed4a9fa99653&scene=0#wechat_redirect

———————以下为原答案———————————

搜了一下,发现没人说这个。
废话不说,直接上图:
Python 有什么奇技淫巧?

在python中,下滑杠代表上一次运行的结果。不要问我为什么,我也不知道。
这个奇技淫巧是我在查scapy的资料的时候意外发现的,网上关于这个技巧的资料似乎也很少,嗯。(顺便提一下,scapy是个非常强大的库,几乎涵盖了所有网络相关的功能,推荐学习。)

再来说一个吧,关于动态修改代码的。直接上代码:

<code class="language-text"># socket.py
#

import sys

del sys.modules['socket']   # 从内存中删除当前的socket包

import sys
import time
import logging
import types

path = sys.path[0]
sys.path.pop(0)    
    

import socket    # 导入真正的socket包

sys.path.insert(0, path)



# 动态path类方法
def re_class_method(_class, method_name, re_method):
    method = getattr(_class, method_name)
    info = sys.version_info
    if info[0] >= 3:   # py2和py3的语法略有不同,需要做下判断。
        setattr(_class, method_name,
                types.MethodType(lambda *args, **kwds: re_method(method, *args, **kwds), _class))
    else:
        setattr(_class, method_name,
                types.MethodType(lambda *args, **kwds: re_method(method, *args, **kwds), None, _class))

# 动态path实例方法
def re_self_method(self, method_name, re_method):
    method = getattr(self, method_name)
    setattr(self, method_name, types.MethodType(lambda *args, **kwds: re_method(method, *args, **kwds), self, self))


# 需要修改的类方法
def re_accept(old_method, self, *args, **kwds):

    return_value = old_method(self, *args, **kwds)
    #do something
    return return_value


# 需要修改的实例方法
def re_recvfrom(old_method, self, *args, **kwds):

    return_value = old_method(*args, **kwds)
    # do something
    return return_value

# 需要修改的类方法(无返回值)
def re_bind(old_method, self, *args, **kwds):
    re_self_method(self, 'recvfrom', re_recvfrom) #把self实例的recvfrom方法替换成re_recvfrom
    #do something
    old_method(self, *args, **kwds)


setattr(socket.socket, '_list_client_ip', {})  #  绑定类属性(socket不能动态绑定实例属性,只好绑定类属性了)
re_class_method(socket.socket, 'bind', re_bind)  #把socket类的bind方法替换成re_bind
re_class_method(socket.socket, 'accept', re_accept)  #把socket类的accept方法替换成re_accept
</code>
登入後複製
也有一个 Python 的奇技淫巧分享给大家,让 Python 的 2+2=5:

<code class="language-python"><span class="n">In</span> <span class="p">[</span><span class="mi">1</span><span class="p">]:</span> <span class="kn">import</span> <span class="nn">ctypes</span>

<span class="n">In</span> <span class="p">[</span><span class="mi">2</span><span class="p">]:</span> <span class="n">ctypes</span><span class="o">.</span><span class="n">memmove</span><span class="p">(</span><span class="nb">id</span><span class="p">(</span><span class="mi">4</span><span class="p">),</span> <span class="nb">id</span><span class="p">(</span><span class="mi">5</span><span class="p">),</span> <span class="mi">24</span><span class="p">)</span>
<span class="n">Out</span><span class="p">[</span><span class="mi">2</span><span class="p">]:</span> <span class="mi">15679760</span>

<span class="n">In</span> <span class="p">[</span><span class="mi">3</span><span class="p">]:</span> <span class="mi">2</span> <span class="o">+</span> <span class="mi">2</span>
<span class="n">Out</span><span class="p">[</span><span class="mi">3</span><span class="p">]:</span> <span class="mi">5</span>
</code>
登入後複製
刚好看到个
Python 有什么奇技淫巧? Python 有什么奇技淫巧?来自于 python高级编程 作者是 @董伟明 说明在分享一个准备给公司讲python高级编程的slide 这里还有对应的视频讲解

====================================================================

另外一个感觉就是这个库了ajalt/fuckitpy · GitHub 中间的实现挺厉害的,访问源码逐行加入try: finally Python没有什么奇技淫巧吧。。。Hidden features of Python 这个链接上有很多小例子
比如for else值得说下。不break的话就执行else
<code class="language-python"><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">10</span><span class="p">:</span>
        <span class="k">break</span>
    <span class="k">print</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
    <span class="k">print</span><span class="p">(</span><span class="s">'10不在里面!'</span><span class="p">)</span>
</code>
登入後複製
其实 PYC 文件很简单:
<code class="language-text">>>> import dis, marshal
>>> with open('hello.pyc', 'rb') as f:
...     f.seek(8)
...     dis.dis(marshal.load(f))
</code>
登入後複製
昨天刚在 StackOverflow 看到的,break 多层循环:python - Breaking out of nested loops
<code class="language-python"><span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">y</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>
        <span class="k">print</span> <span class="n">x</span><span class="o">*</span><span class="n">y</span>
        <span class="k">if</span> <span class="n">x</span><span class="o">*</span><span class="n">y</span> <span class="o">></span> <span class="mi">50</span><span class="p">:</span>
            <span class="k">break</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">continue</span>  <span class="c"># executed if the loop ended normally (no break)</span>
    <span class="k">break</span>  <span class="c"># executed if 'continue' was skipped (break)</span>
</code>
登入後複製
可配置单例,从tornado学来的
Python 有什么奇技淫巧? Stack Overflow上有一个多人编辑整理的答案,非常全而且经常更新:
Hidden features of Python

收藏这个页面,顺便给我的回答点个赞同啊。 1. 元类(metaclass)
PyPy的源码里有个pair和extendabletype
<code class="language-python"><span class="sd">"""</span>
<span class="sd">Two magic tricks for classes:</span>
<span class="sd">    class X:</span>
<span class="sd">        __metaclass__ = extendabletype</span>
<span class="sd">        ...</span>
<span class="sd">    # in some other file...</span>
<span class="sd">    class __extend__(X):</span>
<span class="sd">        ...      # and here you can add new methods and class attributes to X</span>
<span class="sd">Mostly useful together with the second trick, which lets you build</span>
<span class="sd">methods whose 'self' is a pair of objects instead of just one:</span>
<span class="sd">    class __extend__(pairtype(X, Y)):</span>
<span class="sd">        attribute = 42</span>
<span class="sd">        def method((x, y), other, arguments):</span>
<span class="sd">            ...</span>
<span class="sd">    pair(x, y).attribute</span>
<span class="sd">    pair(x, y).method(other, arguments)</span>
<span class="sd">This finds methods and class attributes based on the actual</span>
<span class="sd">class of both objects that go into the pair(), with the usual</span>
<span class="sd">rules of method/attribute overriding in (pairs of) subclasses.</span>
<span class="sd">For more information, see test_pairtype.</span>
<span class="sd">"""</span>

<span class="k">class</span> <span class="nc">extendabletype</span><span class="p">(</span><span class="nb">type</span><span class="p">):</span>
    <span class="sd">"""A type with a syntax trick: 'class __extend__(t)' actually extends</span>
<span class="sd">    the definition of 't' instead of creating a new subclass."""</span>
    <span class="k">def</span> <span class="nf">__new__</span><span class="p">(</span><span class="n">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">name</span> <span class="o">==</span> <span class="s">'__extend__'</span><span class="p">:</span>
            <span class="k">for</span> <span class="n">cls</span> <span class="ow">in</span> <span class="n">bases</span><span class="p">:</span>
                <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="nb">dict</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
                    <span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="s">'__module__'</span><span class="p">:</span>
                        <span class="k">continue</span>
                    <span class="c"># XXX do we need to provide something more for pickling?</span>
                    <span class="nb">setattr</span><span class="p">(</span><span class="n">cls</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
            <span class="k">return</span> <span class="bp">None</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">return</span> <span class="nb">super</span><span class="p">(</span><span class="n">extendabletype</span><span class="p">,</span> <span class="n">cls</span><span class="p">)</span><span class="o">.</span><span class="n">__new__</span><span class="p">(</span><span class="n">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="nb">dict</span><span class="p">)</span>


<span class="k">def</span> <span class="nf">pair</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
    <span class="sd">"""Return a pair object."""</span>
    <span class="n">tp</span> <span class="o">=</span> <span class="n">pairtype</span><span class="p">(</span><span class="n">a</span><span class="o">.</span><span class="n">__class__</span><span class="p">,</span> <span class="n">b</span><span class="o">.</span><span class="n">__class__</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">tp</span><span class="p">((</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">))</span>   <span class="c"># tp is a subclass of tuple</span>

<span class="n">pairtypecache</span> <span class="o">=</span> <span class="p">{}</span>

<span class="k">def</span> <span class="nf">pairtype</span><span class="p">(</span><span class="n">cls1</span><span class="p">,</span> <span class="n">cls2</span><span class="p">):</span>
    <span class="sd">"""type(pair(a,b)) is pairtype(a.__class__, b.__class__)."""</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">pair</span> <span class="o">=</span> <span class="n">pairtypecache</span><span class="p">[</span><span class="n">cls1</span><span class="p">,</span> <span class="n">cls2</span><span class="p">]</span>
    <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
        <span class="n">name</span> <span class="o">=</span> <span class="s">'pairtype(</span><span class="si">%s</span><span class="s">, </span><span class="si">%s</span><span class="s">)'</span> <span class="o">%</span> <span class="p">(</span><span class="n">cls1</span><span class="o">.</span><span class="n">__name__</span><span class="p">,</span> <span class="n">cls2</span><span class="o">.</span><span class="n">__name__</span><span class="p">)</span>
        <span class="n">bases1</span> <span class="o">=</span> <span class="p">[</span><span class="n">pairtype</span><span class="p">(</span><span class="n">base1</span><span class="p">,</span> <span class="n">cls2</span><span class="p">)</span> <span class="k">for</span> <span class="n">base1</span> <span class="ow">in</span> <span class="n">cls1</span><span class="o">.</span><span class="n">__bases__</span><span class="p">]</span>
        <span class="n">bases2</span> <span class="o">=</span> <span class="p">[</span><span class="n">pairtype</span><span class="p">(</span><span class="n">cls1</span><span class="p">,</span> <span class="n">base2</span><span class="p">)</span> <span class="k">for</span> <span class="n">base2</span> <span class="ow">in</span> <span class="n">cls2</span><span class="o">.</span><span class="n">__bases__</span><span class="p">]</span>
        <span class="n">bases</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">bases1</span> <span class="o">+</span> <span class="n">bases2</span><span class="p">)</span> <span class="ow">or</span> <span class="p">(</span><span class="nb">tuple</span><span class="p">,)</span>  <span class="c"># 'tuple': ultimate base</span>
        <span class="n">pair</span> <span class="o">=</span> <span class="n">pairtypecache</span><span class="p">[</span><span class="n">cls1</span><span class="p">,</span> <span class="n">cls2</span><span class="p">]</span> <span class="o">=</span> <span class="n">extendabletype</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="p">{})</span>
    <span class="k">return</span> <span class="n">pair</span>
</code>
登入後複製
相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板