时间:2021-07-01 10:21:17 帮助过:66人阅读
{
"hello": "world",
"this": {
"can": {
"be": "nested"
}
}
}
更新一个最近发现的技巧,一行代码实现多线程/多进程,来源于python开发者微信公众号。# 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
刚好看到个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 loopsfor 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学来的"""
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