是否可以将扩展方法添加到python内置类型中?我知道我可以通过简单地通过添加新方法来将扩展方法添加到定义的类型。如下:
class myClass: pass myClass.myExtensionMethod = lambda self,x:x * 2 z = myClass() print z.myExtensionMethod(10)
但是是将扩展方法添加到python内置类型(如列表,字典,…)的任何方法
list.myExtension = lambda self,x:x * 2 list.myExtension(10)
可以使用以下非常聪明的模块在纯Python中完成此操作:
https://pypi.python.org/pypi/forbiddenfruit
例如:
import functools import ctypes import __builtin__ import operator class PyObject(ctypes.Structure): pass Py_ssize_t = hasattr(ctypes.pythonapi, 'Py_InitModule4_64') and ctypes.c_int64 or ctypes.c_int PyObject._fields_ = [ ('ob_refcnt', Py_ssize_t), ('ob_type', ctypes.POINTER(PyObject)), ] class SlotsPointer(PyObject): _fields_ = [('dict', ctypes.POINTER(PyObject))] def proxy_builtin(klass): name = klass.__name__ slots = getattr(klass, '__dict__', name) pointer = SlotsPointer.from_address(id(slots)) namespace = {} ctypes.pythonapi.PyDict_SetItem( ctypes.py_object(namespace), ctypes.py_object(name), pointer.dict, ) return namespace[name] def die(message, cls=Exception): """ Raise an exception, allows you to use logical shortcut operators to test for object existence succinctly. User.by_name('username') or die('Failed to find user') """ raise cls(message) def unguido(self, key): """ Attempt to find methods which should really exist on the object instance. """ return functools.partial((getattr(__builtin__, key, None) if hasattr(__builtin__, key) else getattr(operator, key, None)) or die(key, KeyError), self) class mapper(object): def __init__(self, iterator, key): self.iterator = iterator self.key = key self.fn = lambda o: getattr(o, key) def __getattribute__(self, key): if key in ('iterator', 'fn', 'key'): return object.__getattribute__(self, key) return mapper(self, key) def __call__(self, *args, **kwargs): self.fn = lambda o: (getattr(o, self.key, None) or unguido(o, self.key))(*args, **kwargs) return self def __iter__(self): for value in self.iterator: yield self.fn(value) class foreach(object): """ Creates an output iterator which will apply any functions called on it to every element in the input iterator. A kind of chainable version of filter(). E.g: foreach([1, 2, 3]).__add__(2).__str__().replace('3', 'a').upper() is equivalent to: (str(o + 2).replace('3', 'a').upper() for o in iterator) Obviously this is not 'Pythonic'. """ def __init__(self, iterator): self.iterator = iterator def __getattribute__(self, key): if key in ('iterator',): return object.__getattribute__(self, key) return mapper(self.iterator, key) def __iter__(self): for value in self.iterator: yield value proxy_builtin(list)['foreach'] = property(foreach) import string print string.join([1, 2, 3].foreach.add(2).str().add(' cookies').upper(), ', ') >>> 3 COOKIES, 4 COOKIES, 5 COOKIES
在那里,感觉不舒服吗?