python: how to extend a huge class with minimum lines of code?

  • Last Update :
  • Techknowledgy :

As explained in the docs you could add your own methods to np.ndarray doing:

import numpy as np

class Ludmo(np.ndarray):
   def sumcols(self):
   return self.sum(axis = 1)

def sumrows(self):
   return self.sum(axis = 0)

def randomize(self):
   self[: ] = np.random.rand( * self.shape)

and then creating the instances using the np.ndarray.view() method:

a = np.random.rand(4, 5).view(Ludmo)

And use the __array_finalize__() method to define new attributes:

def __array_finalize__(self, arr):
   self.foo = 'foo'

Since you ask about a generic solution, here's a generic wrapper class that you can use: (from http://code.activestate.com/recipes/577555-object-wrapper-class/ )

class Wrapper(object):
   ''
'
Object wrapper class.
This a wrapper
for objects.It is initialiesed with the object to wrap
and then proxies the unhandled getattribute methods to it.
Other classes are to inherit from it.
''
'
def __init__(self, obj):
   ''
'
Wrapper constructor.
@param obj: object to wrap ''
'
# wrap the object
self._wrapped_obj = obj

def __getattr__(self, attr):
   # see
if this object has attr
# NOTE do not use hasattr, it goes into
# infinite recurrsion
if attr in self.__dict__:
   # this object has it
return getattr(self, attr)
# proxy to the wrapped object
return getattr(self._wrapped_obj, attr)

update: You would also have to implement __setattr__ the same way, or you would get this

>>> class bla(object):
   ...def __init__(self):
   ...self.a = 1
   ...def foo(self):
   ...print self.a
   ...
   >>>
   d = Wrapper(bla()) >>>
   d.a
1
   >>>
   d.foo()
1
   >>>
   d.a = 2 >>>
   d.a
2
   >>>
   d.foo()
1

and you probably also want to set a new metaclass that intercepts calls to magic functions of new style classes (for full class see https://github.com/hpcugent/vsc-base/blob/master/lib/vsc/utils/wrapper.py for info see How can I intercept calls to python's "magic" methods in new style classes? ) however, this is only needed if you still want to be able to access x.__name__ or x.__file__ and get the magic attribute from the wrapped class, and not your class.

# create proxies
for wrapped object 's double-underscore attributes
class __metaclass__(type):
   def __init__(cls, name, bases, dct):

   def make_proxy(name):
   def proxy(self, * args):
   return getattr(self._obj, name)
return proxy

type.__init__(cls, name, bases, dct)
if cls.__wraps__:
   ignore = set("__%s__" % n
      for n in cls.__ignore__.split())
for name in dir(cls.__wraps__):
   if name.startswith("__"):
   if name not in ignore and name not in dct:
   setattr(cls, name, property(make_proxy(name)))

Suggestion : 2

1 week ago In Python, we can extend a class to create a new class from the existing one. This becomes possible because Python supports the feature of inheritance. Using inheritance, we can make a child class with all the parent class’s features and methods. We can also add new features to the child class other than those present in the parent class. , Python extends is a great feature in python. It’s a keyword as well as a method also. We can use python extend to extend any class and its features into existing code. It is also called inheritance in the object-oriented paradigm. , 4 days ago To create an extend class in Python, you first need to create a new class file. You can do this by opening up a new file in your editor, and then typing the following code: class MyClass: def __init__ (self, name): self.name = name. def my_method (self): , 2 days ago Feb 03, 2020  · The goal of extending a class method in Python can be achieved by Inheritance. One of the major advantages provided by extending a method is that it makes the code reusable. Further, multiple subclasses can share the same code and are even allowed to update it as per the requirement. We’ll deal with both cases here.


import numpy as np class ludmo(object): def __init__(self) self.foo = None self.data = np.array([])

class Wrapper(object): ''
'     Object wrapper class.     This a wrapper for objects. It is initialiesed with the object to wrap     and then proxies the unhandled getattribute methods to it.     Other classes are to inherit from it.     '
''
def __init__(self, obj): ''
'         Wrapper constructor.         @param obj: object to wrap         '
''
# wrap the object self._wrapped_obj = obj def __getattr__(self, attr): # see
if this object has attr # NOTE do not use hasattr, it goes into # infinite recurrsion
if
attr in self.__dict__: # this object has it
return getattr(self, attr) # proxy to the wrapped object
return getattr(self._wrapped_obj, attr)
import numpy as np class ludmo(object): def __init__(self) self.foo = None self.data = np.array([])
import numpy as np class ludmo(np.ndarray): def __init__(self, shape, dtype = float, buffer = None, offset = 0, strides = None, order = None) super().__init__(shape, dtype, buffer, offset, strides, order) self.foo = None
import numpy as np class Ludmo(np.ndarray): def sumcols(self): return self.sum(axis = 1) def sumrows(self): return self.sum(axis = 0) def randomize(self): self[: ] = np.random.rand( * self.shape)
a = np.random.rand(4, 5).view(Ludmo)

Suggestion : 3

Last Updated : 06 Feb, 2020

Output:

Name: PQR
Dimensions: 2, 3, 4
9

Suggestion : 4

Class instantiation uses function notation. Just pretend that the class object is a parameterless function that returns a new instance of the class. For example (assuming the above class):,Of course, a language feature would not be worthy of the name “class” without supporting inheritance. The syntax for a derived class definition looks like this:,Anything that can be done with generators can also be done with class-based iterators as described in the previous section. What makes generators so compact is that the __iter__() and __next__() methods are created automatically.,Having seen the mechanics behind the iterator protocol, it is easy to add iterator behavior to your classes. Define an __iter__() method which returns an object with a __next__() method. If the class defines __next__(), then __iter__() can just return self:

def scope_test():
   def do_local():
   spam = "local spam"

def do_nonlocal():
   nonlocal spam
spam = "nonlocal spam"

def do_global():
   global spam
spam = "global spam"

spam = "test spam"
do_local()
print("After local assignment:", spam)
do_nonlocal()
print("After nonlocal assignment:", spam)
do_global()
print("After global assignment:", spam)

scope_test()
print("In global scope:", spam)
After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam
class ClassName:
<statement-1>
   .
   .
   .
   <statement-N>
class MyClass:
   ""
"A simple example class"
""
i = 12345

def f(self):
   return 'hello world'
x = MyClass()
def __init__(self):
   self.data = []