I have a couple of classes and for testing I need to replicate these classes with small modifications. Initially, I was just changing a test class to the class it is supposed to mimic after doing the necessary modifications.
class Class_A(object):
def __init__(self):
do_class_A_stuff
class Class_B(object):
def __init__(self):
do_class_B_stuff
....
class Test(object):
def __init__(self, classToMimic):
doStuffForTest
self.__class__ = classToMimic
which worked fine. However, now I got to the point that I need to run some test method in between do_classX_stuff. So, I can not run the test specific procedure before I change the class, but also after the init of the super. My thought was just to dynamically inherit Test and overwrite some methods to add the testing code where necessary.
class Test(object):
def __init__(self, classToMimic):
self..__bases__ = classToMimic
def methodToOverwrite(self):
doStuffForTest
Is this a good approach and if so, how can I do that or is there a better solution?
Edit: I had this quite wrong, as Marijn pointed out, I am looking for .bases, not super. changed in the above and goggling this, I found a little bit more information.
Why not use a factory to create subclasses:
def test(classToMimic):
class Test(classToMimic):
def methodToOverwrite(self):
doStuffForTest
return Test
Related
Lets say we have different kind of people, pianist,programmer and multitalented person.
so, How do i inherit like this? currently this code gives error Multitalented has no attribute canplaypiano.
class Pianist:
def __init__(self):
self.canplaypiano=True
class Programer:
def __init__(self):
self.canprogram=True
class Multitalented(Pianist,Programer):
def __init__(self):
self.canswim=True
super(Pianist,self).__init__()
super(Programer,self).__init__()
Raju=Multitalented()
print(Raju.canswim)
print(Raju.canprogram)
print(Raju.canplaypiano)
Also Please mention some well written article about python inheritance/super() i couldnt find a perfect article with clear explaination. thankyou.
All classes involved in cooperative multiple inheritance need to use super, even if the static base class is just object.
class Pianist:
def __init__(self):
super().__init__()
self.canplaypiano=True
class Programer:
def __init__(self):
super().__init__()
self.canprogram=True
class Multitalented(Pianist,Programer):
def __init__(self):
super().__init__()
self.canswim=True
Raju=Multitalented()
print(Raju.canswim)
print(Raju.canprogram)
print(Raju.canplaypiano)
The order in which the initializers run is determined by the method resolution order for Multitalented, which you can affect by changing the order in which Multitalented lists its base classes.
The first, if not best, article to read is Raymond Hettinger's Python's super() Considered Super!, which also includes advice on how to adapt classes the don't themselves use super for use in a cooperative multiple-inheritance hierarchy, as well as advice on how to override a function that uses super (in short, you can't change the signature).
Dont call super with explicit parent classes. In modern python versions (don't know exactly since which version) you call super without parameters. That is, in you case you should have had only one line, not two:
super().__init__()
In somewhat older versions you need to provide the class explicitly, however you should provide the class of "current" object, and the super function takes care of finding out the parent classes. In you case it should be:
super(Multitalented, self).__init__()
Code first:
from abc import abstractmethod
class SomeInterfaceishClass():
#abstractmethod
#staticmethod
def foo(bar):
pass
class SomeClass(SomeInterfaceishClass):
#staticmethod
def foo(bar):
print("implementation here")
class EventHandler():
#staticmethod
#Multitasking.threaded
def foo(bar):
pass
I'm writing a frameworkish thingy where the end-user is forced to implement a few methods (only one here for simplicity). Therefore I have defined the SomeInterfaceishClass class with a abstract method. My problem is that I will not run the method from this class, instead, I'd like to run it from the EventHandler class. As you can see it has a decorator to make it run async and I think this is where the problem arises.
I know that I can call EventHandler.foo = getattr(self, 'foo') in the constructor of SomeInterfaceishClass, but when I do this the complete function will be overridden (loses it's decorator).
I'd like to keep the end-users code as clean as possible and therefore don't really want to add the decorator in SomeClass.
Is there any way to accomplish this? For example is there a way to add an implementation to a class method, rather than add a method to a class?
Just to be clear: I want to add it to the EventHandler class, not an instance of it.
Thank you all! :)
Python 3.6
I just found myself programming this type of inheritance structure (below). Where a sub class is calling methods and attributes of an object a parent has.
In my use case I'm placing code in class A that would otherwise be ugly in class B.
Almost like a reverse inheritance call or something, which doesn't seem like a good idea... (Pycharm doesn't seem to like it)
Can someone please explain what is best practice in this scenario?
Thanks!
class A(object):
def call_class_c_method(self):
self.class_c.do_something(self)
class B(A):
def __init__(self, class_c):
self.class_c = class_c
self.begin_task()
def begin_task(self):
self.call_class_c_method()
class C(object):
def do_something(self):
print("I'm doing something super() useful")
a = A
c = C
b = B(c)
outputs:
I'm doing something super() useful
There is nothing wrong with implementing a small feature in class A and use it as a base class for B. This pattern is known as mixin in Python. It makes a lot of sense if you want to re-use A or want to compose B from many such optional features.
But make sure your mixin is complete in itself!
The original implementation of class A depends on the derived class to set a member variable. This is a particularly ugly approach. Better define class_c as a member of A where it is used:
class A(object):
def __init__(self, class_c):
self.class_c = class_c
def call_class_c_method(self):
self.class_c.do_something()
class B(A):
def __init__(self, class_c):
super().__init__(class_c)
self.begin_task()
def begin_task(self):
self.call_class_c_method()
class C(object):
def do_something(self):
print("I'm doing something super() useful")
c = C()
b = B(c)
I find that reducing things to abstract letters in cases like this makes it harder for me to reason about whether the interaction makes sense.
In effect, you're asking whether it is reasonable for a class(A) to depend on a member that conforms to a given interface (C). The answer is that there are cases where it clearly does.
As an example, consider the model-view-controller pattern in web application design.
You might well have something like
class Controller:
def get(self, request)
return self.view.render(self, request)
or similar. Then elsewhere you'd have some code that found the view and populated self.view in the controller. Typical examples of doing that include some routing lookups or include having a specific view associated with a controller. While not Python, the Rails web framework does a lot of this.
When we have specific examples, it's a lot easier to reason about whether the abstractions make sense.
In the above example, the controller interface depends on having access to some instance of the view interface to do its work. The controller instance encapsulates an instance that implements that view interface.
Here are some things to consider when evaluating such designs:
Can you clearly articulate the boundaries of each interface/class? That is, can you explain what the controller's job is and what the view's job is?
Does your decision to encapsulate an instance agree with those scopes?
Do the interface and class scopes seem reasonable when you think about future extensibility and about minimizing the scope of code changes?
Suppose I have a simple class like this:
class Class1(object):
def __init__(self, property):
self.property = property
def method1(self):
pass
An instances of Class1 returns a value that can be used in other class:
class Class2(object):
def __init__(self, instance_of_class1, other_property):
self.other_property = other_property
self.instance_of_class1 = instance_of_class1
def method1(self):
# A method that uses self.instance_of_class1.property and self.other_property
This is working. However, I have the feeling that this is not a very common approach and maybe there are alternatives. Having said this, I tried to refactor my classes to pass simpler objects to Class2, but I found that passing the whole instance as an argument actually simplifies the code significantly. In order to use this, I have to do this:
instance_of_class1 = Class1(property=value)
instance_of_class2 = Class2(instance_of_class1, other_property=other_value)
instance_of_class2.method1()
This is very similar to the way some R packages look like. Is there a more "Pythonic" alternative?
There's nothing wrong with doing that, though in this particular example it looks like you could just as easily do
instance_of_class2 = Class2(instance_of_class1.property, other_property=other_value).
But if you find you need to use other properties/methods of Class1 inside of Class2, just go ahead and pass the whole Class1 instance into Class2. This kind of approach is used all the time in Python and OOP in general. Many common design patterns call for a class to take an instance (or several instances) of other classes: Proxy, Facade, Adapter, etc.
Apologies if this doesn't make sense, i'm not much of an experienced programmer.
Consider the following code:
import mymodule
class MyClass:
def __init__(self):
self.classInstance = myModule.classInstance()
and then ......
from mymodule import classInstance
class MyClass(classInstance):
def __init__(self):
pass
If I just wanted to use the one classInstance in MyClass, is it ok to import the specific class from the module and have MyClass inherit this class ?
Are there any best practices, or things I should be thinking about when deciding between these two methods ?
Many thanks
Allow me to propose a different example.
Imagine to have the class Vector.
Now you want a class Point. Point can be defined with a vector but maybe it has other extra functionalities that Vector doesn't have.
In this case you derive Point from Vector.
Now you need a Line class.
A Line is not a specialisation of any of the above classes so probably you don't want to derive it from any of them.
However Line uses points. In this case you might want to start you Line class this way:
class Line(object):
def __init__(self):
self.point1 = Point()
self.point2 = Point()
Where point will be something like this:
class Point(Vector):
def __init__(self):
Vector.__init__(self)
So the answer is really: Depends what you need to do, but when you have a clear idea of what you are coding, than choosing between sub-classing or not becomes obvious.
I hope it helped.
You make it sound like you're trying to "choose between" those two approaches, but they do completely different things. The second one defines a class that inherits from a class (confusingly) called classInstance. The first one defines a class called MyClass (not inheriting from anything except the base obect type) that has an instance variable called self.classInstance, which happens to be set to an instance of the classInstance class.
Why are you naming your class classInstance?