好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Python有什么奇技淫巧?

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

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

举个例子,有一个 tester.json 文件,里面的内容是:

 {
    "hello": "world",
    "this": {
        "can": {
            "be": "nested"
        }
    }
}
  
更新一个最近发现的技巧,一行代码实现多线程/多进程,来源于python开发者微信公众号。

首先来看下代码:


import urllib2
from multiprocessing.dummy import Pool as ThreadPool

urls = [
'http://HdhCmsTestpython.org',
'http://HdhCmsTestpython.org/about/',
'http://HdhCmsTestonlamp测试数据/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测试数据/s?__biz=MzA4MjEyNTA5Mw==&mid=2652563685&idx=2&sn=f563f8913630a4334219ed4a9fa99653&scene=0#wechat_redirect

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

搜了一下,发现没人说这个。
废话不说,直接上图:


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

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

 # 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
  
也有一个 Python 的奇技淫巧分享给大家,让 Python 的 2+2=5:

  In   [  1  ]:   import   ctypes 

 In   [  2  ]:   ctypes  .  memmove  (  id  (  4  ),   id  (  5  ),   24  ) 
 Out  [  2  ]:   15679760 

 In   [  3  ]:   2   +   2 
 Out  [  3  ]:   5 
  
刚好看到个
来自于 来自于 python高级编程 作者是 @董伟明 说明在分享一个准备给公司讲python高级编程的slide 这里还有对应的视频讲解

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

另外一个感觉就是这个库了ajalt/fuckitpy · GitHub 中间的实现挺厉害的,访问源码逐行加入try: finally Python没有什么奇技淫巧吧。。。Hidden features of Python 这个链接上有很多小例子
比如for else值得说下。不break的话就执行else

  for   i   in   range  (  10  ): 
     if   i   ==   10  : 
         break 
     print  (  i  ) 
 else  : 
     print  (  '10不在里面!'  ) 
  
其实 PYC 文件很简单:

 >>> import dis, marshal
>>> with open('hello.pyc', 'rb') as f:
...     f.seek(8)
...     dis.dis(marshal.load(f))
  
昨天刚在 StackOverflow 看到的,break 多层循环:python - Breaking out of nested loops

  for   x   in   xrange  (  10  ): 
     for   y   in   xrange  (  10  ): 
         print   x  *  y 
         if   x  *  y   >   50  : 
             break 
     else  : 
         continue    # executed if the loop ended normally (no break) 
     break    # executed if 'continue' was skipped (break) 
  
可配置单例,从tornado学来的
Stack Overflow上有一个多人编辑整理的答案,非常全而且经常更新:
Hidden features of Python

收藏这个页面,顺便给我的回答点个赞同啊。 1. 元类(metaclass)
PyPy的源码里有个pair和extendabletype

  """ 
 Two magic tricks for classes: 
     class X: 
         __metaclass__ = extendabletype 
         ... 
     # in some other file... 
     class __extend__(X): 
         ...      # and here you can add new methods and class attributes to X 
 Mostly useful together with the second trick, which lets you build 
 methods whose 'self' is a pair of objects instead of just one: 
     class __extend__(pairtype(X, Y)): 
         attribute = 42 
         def method((x, y), other, arguments): 
             ... 
     pair(x, y).attribute 
     pair(x, y).method(other, arguments) 
 This finds methods and class attributes based on the actual 
 class of both objects that go into the pair(), with the usual 
 rules of method/attribute overriding in (pairs of) subclasses. 
 For more information, see test_pairtype. 
 """ 

 class   extendabletype  (  type  ): 
     """A type with a syntax trick: 'class __extend__(t)' actually extends 
     the definition of 't' instead of creating a new subclass.""" 
     def   __new__  (  cls  ,   name  ,   bases  ,   dict  ): 
         if   name   ==   '__extend__'  : 
             for   cls   in   bases  : 
                 for   key  ,   value   in   dict  .  items  (): 
                     if   key   ==   '__module__'  : 
                         continue 
                     # XXX do we need to provide something more for pickling? 
                     setattr  (  cls  ,   key  ,   value  ) 
             return   None 
         else  : 
             return   super  (  extendabletype  ,   cls  )  .  __new__  (  cls  ,   name  ,   bases  ,   dict  ) 


 def   pair  (  a  ,   b  ): 
     """Return a pair object.""" 
     tp   =   pairtype  (  a  .  __class__  ,   b  .  __class__  ) 
     return   tp  ((  a  ,   b  ))     # tp is a subclass of tuple 

 pairtypecache   =   {} 

 def   pairtype  (  cls1  ,   cls2  ): 
     """type(pair(a,b)) is pairtype(a.__class__, b.__class__).""" 
     try  : 
         pair   =   pairtypecache  [  cls1  ,   cls2  ] 
     except   KeyError  : 
         name   =   'pairtype(  %s  ,   %s  )'   %   (  cls1  .  __name__  ,   cls2  .  __name__  ) 
         bases1   =   [  pairtype  (  base1  ,   cls2  )   for   base1   in   cls1  .  __bases__  ] 
         bases2   =   [  pairtype  (  cls1  ,   base2  )   for   base2   in   cls2  .  __bases__  ] 
         bases   =   tuple  (  bases1   +   bases2  )   or   (  tuple  ,)    # 'tuple': ultimate base 
         pair   =   pairtypecache  [  cls1  ,   cls2  ]   =   extendabletype  (  name  ,   bases  ,   {}) 
     return   pair 
  

查看更多关于Python有什么奇技淫巧?的详细内容...

  阅读:44次