Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extension method for python built-in types

is it possible to add extension method to python built-in types? I know that I can add extension method to defined type by simply adding new method by . as following:

class myClass:     pass  myClass.myExtensionMethod = lambda self,x:x * 2 z = myClass() print z.myExtensionMethod(10) 

But is any way to adding extension method to python built'in types like list, dict, ...

list.myExtension = lambda self,x:x * 2 list.myExtension(10) 
like image 841
Saeed Afshari Avatar asked Jul 18 '11 20:07

Saeed Afshari


People also ask

What is extension method in Python?

The Python's List extend() method iterates over an iterable like string, list, tuple, etc., and adds each element of the iterable to the end of the List, modifying the original list.

What are the built in type does Python provides?

Python uses five numeric types: Booleans, integers, long integers, floating-point numbers, and complex numbers.

What is types SimpleNamespace?

class types. SimpleNamespace. A simple object subclass that provides attribute access to its namespace, as well as a meaningful repr. Unlike object , with SimpleNamespace you can add and remove attributes.


1 Answers

It can be done in pure Python with this incredibly clever module:

https://pypi.python.org/pypi/forbiddenfruit

For example:

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 

There, doesn't that feel good?

like image 169
toothygoose Avatar answered Oct 02 '22 15:10

toothygoose