Literate Programmin - good explanation.


In [1]:
import hashlib
import inspect
import types

In [2]:
types.ClassType


Out[2]:
classobj

In [15]:
class Bar:
    pass
class Foo(Bar):
    def __getitem__(s):
        pass
type(Foo) is types.ClassType


Out[15]:
True

In [16]:
inspect.getmembers(Foo)


Out[16]:
[('__doc__', None),
 ('__getitem__', <unbound method Foo.__getitem__>),
 ('__module__', '__main__')]

In [2]:
def fdigest(filename):
    f = open(filename,mode='rb')
    m = hashlib.sha256(f.read())
    f.close()
    return m.hexdigest()

In [3]:
h = fdigest('Loads.ipynb')
h


Out[3]:
'3b93953100507915b0198cd96d35331a56d82edf3af433c1da3a1fe6e9f6e070'

In [17]:
def extend(old):
    """This is used as a class decorator to 'extend' class definitions,
    for example, over widely dispersed areas.  EG:

        class Foo(object):
            . . .
        @extend(Foo)
        class Foo:
            def meth2(...):
            . . .

    will result in one class Foo containing all methods, etc."""

    def _extend(new,old=old):
        if new.__name__ != old.__name__:
            raise TypeError("Class names must match: '{}' != '{}'".format(new.__name__,old.__name__))
        if type(new) is not types.ClassType:
            raise TypeError("Extension class must be an old-style class (not derived from class object)")
        if len(new.__bases__) != 0:
            raise TypeError("Extension class must not have a base class.")
        ng = ['__doc__','__module__']
        for a,v in inspect.getmembers(new):
            if a not in ng:
                if type(v) is types.MethodType:
                    if v.im_self is None:
                        v =  types.MethodType(v.im_func,None,old)
                    else:
                        v = classmethod(v.im_func)
                elif type(v) is property:
                    v = property(v.fget,v.fset,v.fdel)
                elif type(v) is types.FunctionType:
                    v = staticmethod(types.FunctionType(v.func_code,v.func_globals,v.func_name,v.func_defaults,v.func_closure))
                setattr(old,a,v)
                #print('Set {} in class {} to type {}'.format(a,old.__name__,type(v)))
        return old
    
    return _extend

In [18]:
class Foo(object):
    def im(s):
        return s
    @classmethod
    def cm(s):
        return s

In [19]:
l = inspect.getmembers(Foo)
l


Out[19]:
[('__class__', type),
 ('__delattr__', <slot wrapper '__delattr__' of 'object' objects>),
 ('__dict__',
  <dictproxy {'__dict__': <attribute '__dict__' of 'Foo' objects>,
   '__doc__': None,
   '__module__': '__main__',
   '__weakref__': <attribute '__weakref__' of 'Foo' objects>,
   'cm': <classmethod at 0xb4c6cc44>,
   'im': <function __main__.im>}>),
 ('__doc__', None),
 ('__format__', <method '__format__' of 'object' objects>),
 ('__getattribute__', <slot wrapper '__getattribute__' of 'object' objects>),
 ('__hash__', <slot wrapper '__hash__' of 'object' objects>),
 ('__init__', <slot wrapper '__init__' of 'object' objects>),
 ('__module__', '__main__'),
 ('__new__', <function __new__>),
 ('__reduce__', <method '__reduce__' of 'object' objects>),
 ('__reduce_ex__', <method '__reduce_ex__' of 'object' objects>),
 ('__repr__', <slot wrapper '__repr__' of 'object' objects>),
 ('__setattr__', <slot wrapper '__setattr__' of 'object' objects>),
 ('__sizeof__', <method '__sizeof__' of 'object' objects>),
 ('__str__', <slot wrapper '__str__' of 'object' objects>),
 ('__subclasshook__', <function __subclasshook__>),
 ('__weakref__', <attribute '__weakref__' of 'Foo' objects>),
 ('cm', <bound method type.cm of <class '__main__.Foo'>>),
 ('im', <unbound method Foo.im>)]

In [18]:
def _cm2(c):
    return 'cm2',c
v = l[-2][1].im_self
Foo.cm2 = types.MethodType(_cm2,v,Foo)
type(v),v,l[-2][1].im_class


Out[18]:
(type, __main__.Foo, __main__.Foo)

In [19]:
l = inspect.getmembers(Foo)
l


Out[19]:
[('__class__', type),
 ('__delattr__', <slot wrapper '__delattr__' of 'object' objects>),
 ('__dict__',
  <dictproxy {'__dict__': <attribute '__dict__' of 'Foo' objects>,
   '__doc__': None,
   '__module__': '__main__',
   '__weakref__': <attribute '__weakref__' of 'Foo' objects>,
   'cm': <classmethod at 0x7f226432d1d8>,
   'cm2': <bound method Foo._cm2 of <class '__main__.Foo'>>,
   'im': <function __main__.im>}>),
 ('__doc__', None),
 ('__format__', <method '__format__' of 'object' objects>),
 ('__getattribute__', <slot wrapper '__getattribute__' of 'object' objects>),
 ('__hash__', <slot wrapper '__hash__' of 'object' objects>),
 ('__init__', <slot wrapper '__init__' of 'object' objects>),
 ('__module__', '__main__'),
 ('__new__', <function __new__>),
 ('__reduce__', <method '__reduce__' of 'object' objects>),
 ('__reduce_ex__', <method '__reduce_ex__' of 'object' objects>),
 ('__repr__', <slot wrapper '__repr__' of 'object' objects>),
 ('__setattr__', <slot wrapper '__setattr__' of 'object' objects>),
 ('__sizeof__', <method '__sizeof__' of 'object' objects>),
 ('__str__', <slot wrapper '__str__' of 'object' objects>),
 ('__subclasshook__', <function __subclasshook__>),
 ('__weakref__', <attribute '__weakref__' of 'Foo' objects>),
 ('cm', <bound method type.cm of <class '__main__.Foo'>>),
 ('cm2', <bound method Foo._cm2 of <class '__main__.Foo'>>),
 ('im', <unbound method Foo.im>)]

In [20]:
def _cm3(c):
    return '_cm3',c
Foo.cm3 = classmethod(_cm3)
l = inspect.getmembers(Foo)
l


Out[20]:
[('__class__', type),
 ('__delattr__', <slot wrapper '__delattr__' of 'object' objects>),
 ('__dict__',
  <dictproxy {'__dict__': <attribute '__dict__' of 'Foo' objects>,
   '__doc__': None,
   '__module__': '__main__',
   '__weakref__': <attribute '__weakref__' of 'Foo' objects>,
   'cm': <classmethod at 0x7f226432d1d8>,
   'cm2': <bound method Foo._cm2 of <class '__main__.Foo'>>,
   'cm3': <classmethod at 0x7f226432d210>,
   'im': <function __main__.im>}>),
 ('__doc__', None),
 ('__format__', <method '__format__' of 'object' objects>),
 ('__getattribute__', <slot wrapper '__getattribute__' of 'object' objects>),
 ('__hash__', <slot wrapper '__hash__' of 'object' objects>),
 ('__init__', <slot wrapper '__init__' of 'object' objects>),
 ('__module__', '__main__'),
 ('__new__', <function __new__>),
 ('__reduce__', <method '__reduce__' of 'object' objects>),
 ('__reduce_ex__', <method '__reduce_ex__' of 'object' objects>),
 ('__repr__', <slot wrapper '__repr__' of 'object' objects>),
 ('__setattr__', <slot wrapper '__setattr__' of 'object' objects>),
 ('__sizeof__', <method '__sizeof__' of 'object' objects>),
 ('__str__', <slot wrapper '__str__' of 'object' objects>),
 ('__subclasshook__', <function __subclasshook__>),
 ('__weakref__', <attribute '__weakref__' of 'Foo' objects>),
 ('cm', <bound method type.cm of <class '__main__.Foo'>>),
 ('cm2', <bound method Foo._cm2 of <class '__main__.Foo'>>),
 ('cm3', <bound method type._cm3 of <class '__main__.Foo'>>),
 ('im', <unbound method Foo.im>)]

In [28]:
v = l[-2][1]
v.im_self, type(v)


Out[28]:
(__main__.Foo, instancemethod)

In [21]:
Foo.cm(), Foo.cm2()


Out[21]:
(__main__.Foo, ('cm2', __main__.Foo))

In [22]:
class Bar(Foo):
    pass

In [23]:
Bar.cm(), Bar.cm2()


Out[23]:
(__main__.Bar, ('cm2', __main__.Foo))

In [24]:
Bar.cm3()


Out[24]:
('_cm3', __main__.Bar)

In [29]:
from salib import extend

In [30]:
class Zip(object):
    def im(c):
        return 'Zip.im',c
    @classmethod
    def cm(c):
        return 'Zip.cm',c

In [32]:
@extend(Zip)
class Zip:
    def im2(c):
        return 'Zip.im2',c
    @classmethod
    def cm2(c):
        return 'Zip.cm2',c

In [34]:
z = Zip()
z.im(), z.cm(), z.im2(), z.cm2()


Out[34]:
(('Zip.im', <__main__.Zip at 0x7f2264183dd0>),
 ('Zip.cm', __main__.Zip),
 ('Zip.im2', <__main__.Zip at 0x7f2264183dd0>),
 ('Zip.cm2', __main__.Zip))

In [35]:
class Zap(Zip):
    def im3(c):
        return 'Zap.im3',c
    @classmethod
    def cm3(c):
        return 'Zap.cm3',c

In [36]:
zz = Zap()
zz.im(), zz.cm(), zz.im2(), zz.cm2(), zz.im3(), zz.cm3()


Out[36]:
(('Zip.im', <__main__.Zap at 0x7f2264183ed0>),
 ('Zip.cm', __main__.Zap),
 ('Zip.im2', <__main__.Zap at 0x7f2264183ed0>),
 ('Zip.cm2', __main__.Zap),
 ('Zap.im3', <__main__.Zap at 0x7f2264183ed0>),
 ('Zap.cm3', __main__.Zap))

No args to @extend?

The following trick might be usable to extract the old class when its not specifically given to @extend.


In [20]:
class Zoop:
    pass

In [21]:
Zoop.__module__


Out[21]:
'__main__'

In [22]:
import sys
m = sys.modules['__main__']

In [23]:
m


Out[23]:
<module '__main__' (built-in)>

In [26]:
getattr(m,'Zoop')


Out[26]:
<class __main__.Zoop at 0xb4cac6bc>

In [27]:
c = Zoop
m.__dict__[c.__name__]


Out[27]:
<class __main__.Zoop at 0xb4cac6bc>

'test' magic


In [2]:
from IPython.core.magic import register_cell_magic

In [3]:
@register_cell_magic('test')
def _test(line,cell):
    print('Line:',line)
    print('Cell:',cell)
    return 13

In [6]:
%%test foo be doo
a + b
c


('Line:', u'     foo be doo            ')
('Cell:', u'a + b\nc')
Out[6]:
13

In [15]:
%%time
n = 1000000
sum(range(n))


CPU times: user 36 ms, sys: 0 ns, total: 36 ms
Wall time: 35.4 ms

In [19]:
%lsmagic


Out[19]:
Available line magics:
%alias  %alias_magic  %autocall  %automagic  %autosave  %bookmark  %cat  %cd  %clear  %colors  %config  %connect_info  %cp  %debug  %dhist  %dirs  %doctest_mode  %ed  %edit  %env  %gui  %hist  %history  %install_default_config  %install_ext  %install_profiles  %killbgscripts  %ldir  %less  %lf  %lk  %ll  %load  %load_ext  %loadpy  %logoff  %logon  %logstart  %logstate  %logstop  %ls  %lsmagic  %lx  %macro  %magic  %man  %matplotlib  %mkdir  %more  %mv  %notebook  %page  %pastebin  %pdb  %pdef  %pdoc  %pfile  %pinfo  %pinfo2  %popd  %pprint  %precision  %profile  %prun  %psearch  %psource  %pushd  %pwd  %pycat  %pylab  %qtconsole  %quickref  %recall  %rehashx  %reload_ext  %rep  %rerun  %reset  %reset_selective  %rm  %rmdir  %run  %save  %sc  %set_env  %store  %sx  %system  %tb  %time  %timeit  %unalias  %unload_ext  %who  %who_ls  %whos  %xdel  %xmode

Available cell magics:
%%!  %%HTML  %%SVG  %%bash  %%capture  %%debug  %%file  %%html  %%javascript  %%latex  %%perl  %%prun  %%pypy  %%python  %%python2  %%python3  %%ruby  %%script  %%sh  %%svg  %%sx  %%system  %%test  %%time  %%timeit  %%writefile

Automagic is ON, % prefix IS NOT needed for line magics.

In [52]:
cc = compile('''a=3;
b=4;
c=a*b;
c*10''','here','exec')

In [54]:
eval(cc)

In [53]:
cc


Out[53]:
<code object <module> at 0x7f13785c1330, file "here", line 1>

In [48]:
cc.co_code


Out[48]:
'd\x00\x00Z\x00\x00d\x01\x00S'

In [49]:
dir(cc)


Out[49]:
['__class__',
 '__cmp__',
 '__delattr__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__le__',
 '__lt__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 'co_argcount',
 'co_cellvars',
 'co_code',
 'co_consts',
 'co_filename',
 'co_firstlineno',
 'co_flags',
 'co_freevars',
 'co_lnotab',
 'co_name',
 'co_names',
 'co_nlocals',
 'co_stacksize',
 'co_varnames']

In [50]:
cc.co_filename


Out[50]:
'here'

In [ ]: