Search code examples
pythonoopstaticinstanceinstance-variables

Python : use a class methods as static , when its implemented as instance methods


I have a big class which has a lot of functions and attributes. the instances are created from data in a remote database.

the process of creating each instance is very long and heavy.

In performance sake ive created a bunch class from this heavy class. so accessing the attributed is easy and works great . the problem is how to use the methods from that class.

ex :

class clsA():
   def __init__(self,obj):
        self.attrA=obj.attrA
   def someFunc(self):
        print self
class bunchClsA(bunch):
   def __getattr__(self, attr):
       # this is the problem:
       try:
            #try and return a func
            func = clsA.attr
            return func
       except:
            # return simple attribute 
            return self.attr

Clearly this dosent work , Is there a way i could access the instance function staticly and override the "self" var ?


Solution

  • Found out a nice solution to the problem :

    from bunch import Bunch
    import types
    #Original class: 
    class A():
      y=6
      def __init__(self,num):
        self.x=num
      def funcA(self):
        print self.x
    
    #class that wraps A using Bunch(thats what i needed .. u can use another):
    class B(Bunch):
      def __init__(self, data, cls):
        self._cls = cls # notice, not an instance just the class it self
        super(B, self).__init__(data)
    
      def __getattr__(self, attr):
        # Handles normal Bunch, dict attributes
        if attr in self.keys():
          return self[attr]
        else:
          res = getattr(self._cls, attr)
          if isinstance(res, types.MethodType):
            # returns  the class func with self overriden
            return types.MethodType(res.im_func, self, type(self))
          else:
            # returns class attributes like y 
            return res
    
    data = {'x': 3}
    ins_b = B(data, A)
    print ins_b.funcA() # returns 3
    print ins_b.y # returns 6
    

    And this solves my issue, its a hack and if you have the privileges, redesign the code.