0.这个问题虽说是找寻“奇技淫巧”,但其实是想抛砖引玉
1.如果想把自己认为或好玩或强大的python使用技巧拿出来跟大家分享,可否稍微详细的讲解一下
<code class="language-text">{ "hello": "world", "this": { "can": { "be": "nested" } } } </code>
<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>
<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>
<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>
<code class="language-text">>>> import dis, marshal >>> with open('hello.pyc', 'rb') as f: ... f.seek(8) ... dis.dis(marshal.load(f)) </code>
<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>
<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>