masdeseiscaracteres
8/31/2016 - 7:59 AM

Python classes

Python classes

def print_classtree(cls, indent=2):
    print('.' * indent, cls.__module__ + "." + cls.__name__)
    for supercls in cls.__bases__:
        print_classtree(supercls, indent + 3)
class mixedmethod(object): # descriptor
    def __init__(self, f):
        self.f = f

    def __get__(self, obj, klass=None):
        if obj is not None:
            _arg = obj
        else:
            _arg = klass

        def newfunc(*args):
            return self.f(_arg, *args)

        return newfunc

class C:
    def im(self):
        """Instance (c) passed to instance methods as first argument when called as c.im()"""
        print(type(self))

    @classmethod
    def cm(cls):
        """Class (C) passed to class methods as first argument when called as either C.im() or c.im()"""
        print(type(cls))

    @staticmethod
    def sm():
        """No arguments passed to static methods when called as either C.im() or c.im()"""

    @mixedmethod
    def mm(this):
        """Class (C) or instance (c) passed to mixed methods as first argument when
        called as C.im() or c.im(), respectively"""
        print(type(this))

    # Binding: in general methods are bound as: C.__dict__['m'].__get__(c, C)
from types import MethodType
from pandas import DataFrame

def func(arg=None, n=0):
    print(arg)
    print(arg.a+arg.b+n)

class C:
    b=1
    def __init__(self, a=2):
        self.a = a

    #instance method
    def add_methods_from_instance(self):
        self.instance_method_instance = func
        self.instance_method_instance2 = MethodType(func, self)
        self.__class__.instance_method_instance3 = func
        self.__class__.class_method_instance = classmethod(func)
        self.__class__.static_method_instance= staticmethod(func)

    @classmethod
    def add_methods_from_class(cls):
        cls.instance_method_class = func
        cls.class_method_class = classmethod(func) #OK!
        cls.class_method_class2 = MethodType(func, cls)
        cls.static_method_class = staticmethod(func)

    @staticmethod
    def add_methods_from_static_flexible(arg):
        arg.instance_method_static = func
        arg.class_method_static = classmethod(func)
        arg.static_method_static = staticmethod(func)

        arg.method_static = MethodType(func, arg)

    @staticmethod
    def add_methods_from_static_fixed():
        C.instance_method_static = func
        C.class_method_static = classmethod(func) #WRONG, cannot be called from an instance
        C.class_method_static2 = MethodType(func, C)

        C.static_method_static = staticmethod(func)

#########################################################

C.add_methods_from_class()
c=C()

c.add_methods_from_instance()

#########################################################

cC = C
cC.add_methods_from_static_flexible(C)
print(c.method_static) #instancemethod

cC.add_methods_from_static_flexible(C)
print(C.method_static) #classmethod

cC.add_methods_from_static_flexible(c)
print(C.method_static) #classmethod

cC.add_methods_from_static_flexible(c)
print(c.method_static) #instancemethod

#################################
cC = C
cC.add_methods_from_static_fixed()
print(C.class_method_static) #bound classmethod
print(c.class_method_static) #unbound classmethod, WRONG?

cC.add_methods_from_static_fixed()
print(C.class_method_static2) #classmethod
print(c.class_method_static2) #classmethod