Implement same methods in different classes - python

I really don't know how to word this problem, so I'll try to explain it with an example.
Let's say I have three GUI classes:
Base Surface class
Detailed Surface Class
Sprite Class
All of them are independent of each other, no inheritance among them.
Now I have a function "drag()" that makes a surface/sprite dragable, and I want to implement this function as a method for all three of them.
Since it's the exact same code for all implementations I find it annoying, cumbersome and bad practice to rewrite the code.
The only thing I came up with so far was to make a saperate class for it and inherit this class. But that also doesn't seem to be the way to go.
I'd be very thankfull for some advice.
EDIT
Another example with a slightly different setup - I have the following classes:
BaseSurface
Dragable
Resizable
EventHandler
Only the first one is independent, the others depend on the first (must be inherited).
The end user should, without any effort, be able to choose between a simple BaseSurface, one with that implements dragable, one with resizable, one with eventHandler, and any combination. By "without any effort" I mean the end user should not have to make e custom Class and inherit the desired classes plus call the appropriate methods (init, update, ...) that some classes share.
So what I could do is make a class for every possible combination, eg.
"BaseSurfaceDrag", "BaseSurfaceDragResize", ...
which will get messy really quickly. Whats a different and better approach to this?

This is exactly the kind of case that you should use a parent class for. In both cases it looks like your parent class (logically) should be something like:
class Drawable(object):
def drag(self, *args, **kwargs):
"""Drag and drop behavior"""
# Your code goes here
Then each of your other classes inherits from that
class BaseSurface(Drawable):
# stuff
class DetailedSurface(Drawable):
# stuff
class Sprite(Drawable):
# stuff
In the second case what you have are interfaces, so you could logically do something like:
class DragInterface(object):
"""Implements a `drag` method"""
def drag(self):
"""Drag and drop behavior"""
# Your code goes here
class ResizeInterface(object):
"""Implements a `resize` method"""
def resize(self):
"""Drag and drop resize"""
# Code
class EventHandlerInterface(object):
"""Handles events"""
def handle(self, evt):
# Code
class MyNewSurface(BaseSurface, DragInterface, ResizeInterface):
"""Draggable, resizeable surface"""
# Implement here

Related

PyQt5 QGraphicsItem odd inheritance behaviour

This is a problem I've found the solution to, but not the answer to. The following is the relevant part of my code:
class MyClass(QGraphicsPolygonItem, MyAbstractGraphicsShapeItem, MyGraphicsItem)
def __init__(self):
super(MyClass, self).__init__()
The first class is the type of graphics object I'm trying to create. For me, the first one I did was a polygon. The second class is one which needed to inherit QAbstractGraphicsShapeItem to change the objects color through. The third class works with any QGraphicsItem. To make everything modular and reusable, this was my setup.
The issue I faced was as such:
If the first class was after the second class, MyClass would no longer recognize it had a polygon I could set.
If the third class was before the second class, MyClass would stop painting itself, showing up in no way on screen.
As you can see, the sequence shown in my code is the only one that works. One of the sequences (third, first, second) even crashes the program. Here is what I think happens:
The graphic item classes inherit in this order, from superclass <--- subclass.
QGraphicsItem <--- QAbstractGraphicsShapeItem <--- QGraphicsPolygonItem
When the initialization priority is the same as the inheritance direction from subclasses to superclasses, the inheritance works.
The Point
This is what I think the initialization order looks like in these situations:
MyAbstractgraphicsShapeItem, QGraphicsPolygonItem, MyGraphicsItem, QAbstractGraphicsShapeItem, QGraphicsItem
QGraphicsPolygonItem, MyGraphicsItem, MyAbstractgraphicsShapeItem, QAbstractGraphicsShapeItem, QGraphicsItem
QGraphicsPolygonItem, MyAbstractgraphicsShapeItem, MyGraphicsItem, QAbstractGraphicsShapeItem, QGraphicsItem
Where the third is the working one.
I cannot see the difference between them. I know how it should work but not why. The initialization order shouldn't matter, as the super call should order them like this, where there are no conflicts between functionality. I know that QAbstractGraphicsShapeItem doesn't have boundingRect or paint functions, but I believe they should be overwritten by QGraphicsPolygonItem class functions. I would like an answer, because this was a really baffling issue to solve.
Edit:
I'll add the other two classes, just the relevant parts:
class MyGraphicsItem(QGraphicsItem):
def __init__(self):
super(MyQGraphicsItem, self).__init__()
class MyAbstractGraphicsShapeItem(QAbstractGraphicsShapeItem):
def __init__(self):
super(MyAbstractGraphicsShapeItem, self).__init__()
For additional detail, MyGraphicsItem allows me to place graphics items in relation to the parent as I wish, while MyAbstractGraphicsShapeItem allows me to create button like behavior (since QAbstractButton only works with QWidgets).

Can I add methods to class by condition and call them?

Here's my problem:
I have a class. And I have two objects of that class: ObjectOne and ObjectTwo
I'd like my class to have certain methods for ObjectOne and different methods for ObjectTwo.
I'd also like to choose those methods from a variety depending on some condition.
and of course, I need to call the methods I have 'from the outside code'
As I see the solution on my own (just logic, no code):
I make a default class. And I make a list of functions defined somewhere.
IF 'some condition' is True I construct a child class that takes one of those functions and adds it into class as class method. Otherwise I add some default set of methods. Then I make ObjectOne of this child class.
The question is: can I do that at all? And how do I do that? And how do I call such a method once it is added? They all would surely be named differently...
I do not ask for a piece of working code here. If you could give me a hint on where to look or maybe a certain topic to learn, this would do just fine!
PS: In case you wonder, the context is this: I am making a simple game prototype, and my objects represent two game units (characters) that fight each other automatically. Something like an auto-chess. Each unit may have unique abilities and therefore should act (make decisions on the battlefield) depending on the abilities it has. At first I tried to make a unified decision-making routine that would include all possible abilities at once (such as: if hasDoubleStrike else if... etc). But it turned out to be a very complex task, because there are tens of abilities overall, each unit may have any two, so the number of combinations is... vast. So, now I am trying to distribute this logic over separate units: each one would 'know' only of its own two abilities.
I mean I believe this is what would generally be referred to as a bad idea, but... you could have an argument passed into the class's constructor and then define the behavior/existence of a function depending on that condition. Like So:
class foo():
def __init__(self, condition):
if condition:
self.func = lambda : print('baz')
else:
self.func = lambda : print('bar')
if __name__ == '__main__':
obj1 = foo(True)
obj2 = foo(False)
obj1.func()
obj2.func()
Outputs:
baz
bar
You'd likely be better off just having different classes or setting up some sort of class hierarchy.
So in the end the best solution was the classical factory method and factory class. Like this:
import abc
import Actions # a module that works as a library of standard actions
def make_creature(some_params):
creature_factory = CreatureFactory()
tempCreature = creature_factory.make_creature(some_params)
return tempCreature
class CreatureFactory:
def make_creature(some_params):
...
if "foo" in some_params:
return fooChildCreature()
class ParentCreature(metaclass=abc.ABCMeta):
someStaticParams = 'abc'
#abc.abstractmethod
def decisionMaking():
pass
class fooChildCreature(ParentCreature):
def decisionMaking():
Actions.foo_action()
Actions.bar_action()
# some creature-specific decision making here that calls same static functions from 'Actions'
NewCreature = make_creature(some_params)
This is not ideal, this still requires much manual work to define decision making for various kinds of creatures, but it is still WAY better than anything else. Thank you very much for this advice.

Python inheritance structure

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?

Keeping classes loosely coupled and sharing data

I've been working in python on a project where I have a GUI which I split up a bunch of the work between classes. I don't know a lot of the best practices for passing data around between classes, and I've frequently run into the issue, where I have to implement something, or change something for work, and I've resorted to making a lot of the classes objects of another class in order to give it the data I need.
Any ideas or suggests would be greatly appreciated on how to keep my classes independent for later modification and still pass the relevant data around without affecting interfaces too much?
As an example
class Window():
def __init__(self, parent=None):
self.parent = parent
def doStuff(self):
#do work here
class ParseMyWork(Window):
def __init__(self, parent=None):
self.parent=parent
I often find myself doing stuff like the above giving objects to class Window
or simply inheriting everything from them as in ParseMyWork
There must be better and cleaner ways of passing data around without making my classes utterly dependent on eachother, where one little change creates a cascade effect that forces me to make changes in a bunch of other classes.
Any answers to the question don't necessarily have to be in python, but it will be helpful if they are
If I'm understanding your question correctly, I would say that inheritance is not necessary in your case. Why not give ParseMyWork a function for dealing with a specific Window task?
class Window():
def __init__(self, parent=None):
self.parent = parent
def doStuff(self):
#do work here
class ParseMyWork():
def __init__(self, parent=None):
self.parent=parent`
def doWindowActivity(self, window):
window.doStuff
Then you can use the function like this
work_parser = ParseMyWork()
window = Window()
work_parser.doWindowActivity(window);
That way you can use your work_parse instance with any window instance.
Apologies in advance for my Python, it's been a while so if you see any rookie mistakes, do point them out.
Keep it simple.py:
def doStuff(window):
#do work here
return window
def parseStuff(stuff):
pass
really.py:
from simple import doStuff, parseStuff
def really_simple(window):
okay = doStuff(window)
return parseStuff(okay)
don't complicate the class:
from really import really_simple
really_simple(window)
imo: classes are overly complicated objects, and in a lot of cases more confusing than they need to be, plus they hold references and modify stuff, and can be difficult to decouple once they have been tied to other classes. if there isn't a clear reason why a class needs to be used, then it probably doesn't need to be used.
Classes are super powerful, so it's good you're getting started with em.
Discalimer: Haven't worked in python for a while now, so things might not be exact. The general idea still applies though.
Getting into your question now:
I would say the best way to achieve what you want is to create an instance of the first object where you will extract information from.
Now when creating a class, it's vital that you have attributes within them that you will want to be stored within it that you would like to retrieve once the class is instantiated.
For example, using your Window class example above, let's say that you have an attribute called resolution. It would look something like this:
class Window():
def __init__(self, parent = None):
self.parent = None
self.resolution = '40x80'
Now the resolution information associated with your Window class is forever part of any Window class instance. Now, the next step would be to create a get method for resolution. This should be done as follow:
class Window():
def __init__(self, parent = None):
self.parent = None
self.resolution = '40x80'
def getResoultion():
return self.resolution
Now, the reason we created this get method is because we can now set a variable to the information that is returned with it.
So let's say that you have everything associated with your Window class in its own file (let's say the file name is called Window.py). In a separate file (let's call it main.py), you can do the following:
import Window
windowInstance = Window()
windowResolution = windowInstance.getResolution()
If you print out the variable windowResolution, you should get that 40x80 printed out.
Now, as a side note, I do believe it is possible to get the information associated with an attribute with an instance of a class by simply doing something like
windowResolution = windowInstance.resolution
but that is bad practice in general. The reason, in a nutshell, is because you are now exposing attribute names of your class which you do not want to do because it makes it easy for a person outside of your code to learn the name where that information is held and change it. This can then lead to a myriad of other problems when it comes to making an overall program work. That is why it is best practice to use getters and setters. I already showed what getters are. Simply a get method for attributes. Setters, as you can probably assume, allow for one to set the information of an attribute to something else. Now you might say "Gabe, if we can create setter methods, what's the point of it if they just change it". My answer to that is to not give a setter method to all attributes. For attributes you don't mind for a person to change, give it a setter method, but for attributes you do not want any outside users to touch, simply don't create a setter method for it. Same goes with getter methods too. Users don't need to see all of the information of all attributes that makes your program work. Here's a better explanation: https://en.wikipedia.org/wiki/Mutator_method
Now, back to your example. Now let's say you have your ParseMyWork class in its own file like we did with your Window class, and let's say that ParseMyWork needs the resolution info from Window class. You can do the following :
import Window
import ParseMyWork
windowInstance = Window()
windowResolution = windowInstance.getResolution()
parseInstance = ParseMyWork(windowResolution)
This will only pass the window resolution information associated with your Window class. Hope this helps.

python how to structure this class

Im having some trouble deciding the best way to structure a certain class. The class will take in some strings as settings and the methods will create different kinds of charts based on the settings....
for example. It could be called like this...
c = ChartEngine(type='line', labels='foo bar', data='1, 2', data2='3, 4')
chart = c.make_chart()
IDK if it is best to structure this as a class, or just a function that will call other functions in the same module...IDK if I should just put logic in the __init__ function that will setup to call the make_chart function or if there is some other way.
def __init__(*settings*):
self.type = type
self.labels = labels
self.data = data
....
make_chart(self.type, self.labels, self.data):
if self.type == "line":
line_chart(settings)
elif self.type == "bar":
bar_chart(settings)
...
How would you structure a class like this?
Use tests as a design tool. Write a test for one trivial minimal feature you want. Let it fail, then write the minimal code required to make it pass. Then write a other test with an other feature, let it fail and so on. Using this development cycle (TDD), you design from the user point of view and enforce proper encapsulation and abstraction of your implementation. You may want to learn about the pytest module.
At first sight I'd say that your class as you plan it will know too much about too many different things. Read about SRP and other SOLID principles to get you started on the matter. Most importantly, implement only what you need now, nothing more.
Finaly, ChartEngine looks like a use case for the abstract factory pattern which can be hard to implement with elegant code. Start with the most simple use cases and refactor early.
This is a design problem. By nature of the problem, you could use many subjective approaches. You'd optimally like to design your program in such a way that your source is generally de-coupled, leading to future changes being trivial. However over-engineering is a thing, so take into account the requirements at hand. Various approaches could yield certain benefits. Here is an example approach below.
You could have a master control class called ChartEngine (as you've mentioned) that can dispatch the various charts via Chart sub-classes. You could then implement a base class called Chart that serves as the super class to the various variations. The nature of your program suits inheritance more than composition in my opinion (again, many different approaches can be used).
class Chart(object):
def __init__(self):
pass
def draw(self):
pass
...
Then extend/override the base class' functionality via the inheritance of Chart. You could then implement something like a Line class for example:
class Line(Chart):
pass
class Bar(Chart):
pass
As for ChartEngine, you could could have the class have dispatch methods for each of the various graph types similar to routes in a MVC web app. One approach could be to have a dictionary that keeps track of the various graphs and their associated dispatch methods.
class ChartEngine(object):
type_to_dispatch = {"bar" : dispatch_bar, "line" : dispatch_line}
def __init__(self, type, labels, data):
self.type = type
self.labels = labels
self.data = data
...
def make_chart(self):
type_to_dispatch[self.type]()
def dispatch_line(self):
pass
def dispatch_bar(self):
pass

Categories