This question already has answers here:
Is it possible to do partial inheritance with Python?
(4 answers)
Closed 8 months ago.
I have a parent class with a lot of methods. I want some of them inherited in all of the child classes. Some of the methods I only want in certain classes. Can I somehow select which methods to inherit. I know I could override them in the child class, but I would prefer a positive approach of adding what you want instead of overriding the ones you don't want.
I am using the backtrader library.
class BaseStrategy(bt.Strategy):
def notify_cashvalue(self, cash, value):
if value < self.starting_cash * self.terminate_threshold:
self.log(f'Stopping strategy at due drop below {self.terminate_threshold * 100}% of initial cash.')
self.cerebro.runstop()
This is the class I want inherit from. As you see parent class is a child class to the library base, but this class implements empty methods.
Methods like notify_cashvalue are always called when this class is used. In my example notify_cashvalue has some attributes that will not be defined in all the child classes, so there would an error as notify_cashvalue is allways called, as are several other functions, which I want to selectively inherit.
I found here Is it possible to do partial inheritance with Python? that you can select the methods you want in this way:
class Class0():
def hello():
return "Hello"
def bye():
pass
def nice():
pass
class Class1():
Hello = Class0.hello
Related
Is it possible in python for a nested class to extend its parent?
Like this:
class Parent:
class Child(Parent):
pass
child = Parent.Child()
Is it possible to do this in the opposite direction?
Like this:
class Parent(Child):
class Child:
pass
parent = Parent()
From what I know this is not possible, even with from __future__ import annotations.
The best known way around this is just not to make nested classes.
Important:
The purpose of this question is to make it clear if this is even possible in the python language.
There is no "final goal", objectives to be accomplished with this approach or justification for it.
Don't spam in the comments/answers about "how bad this code is".
No and Yes.
No, because when you inherit from a class, that class must be defined before you can inherit from it. Neither of your code examples will work due to this.
Yes, because Python is a dynamic language and you can change (monkey-patch) the base classes even after defining them:
class Temp:
pass
# example 1
class Parent:
class Child(Temp):
pass
Parent.Child.__bases__ = (Parent,)
# example 2
class Parent(Temp):
class Child:
pass
Parent.__bases__ = (Parent.Child,)
Why use the Temp class?
Classes automatically inherit from object. Due to a bug (https://bugs.python.org/issue672115), we cannot change __bases__ if a class inherits from object. Hence, we inherit from a temporary (Temp) class to avoid that issue.
This question already has answers here:
Is it possible to make abstract classes?
(14 answers)
Closed 5 years ago.
I use pep8 in visual studio code and I just tried to write some abstract classes.
The problem is I get the error [pylint] E1101:Instance of 'MyAbstract' has no 'child_method' member because pep8 does not realise that the method is well defined, but in the child classes.
To illustrate my problem here is a code snippet that is reducted to the minimum for clarity:
class MyAbstract:
def some_method(self):
newinfo = self.child_method()
# use newinfo
class MyChild(MyAbstract):
def child_method(self):
# Do something in a way
class OtherChild(MyAbstract):
def child_method(self):
# Do the same thing in a different way
So my questions are:
Is it ok to write classes like this?
How would you solve the error? (disable error, use another pattern, ...)
Clarification
The MyAbstract class shouldn't be instanciated, and the child classes will inherit the some_method. The idea is to use it on child class instances.
If you want MyAbstract to be an abstract class with abstract method child_method, Python has a way of expressing that in the abc module:
import abc
class MyAbstract(metaclass=abc.ABCMeta):
#abc.abstractmethod
def child_method(self):
pass
def some_method(self):
newinfo = self.child_method()
do_whatever_with(newinfo)
Your linter will no longer complain about the nonexistent method, and as a bonus, Python will detect attempts to instantiate a class with unimplemented abstract methods.
This question already has answers here:
Python class attribute referencing
(2 answers)
Closed 7 years ago.
Is it possible to access self.bin outside the class?
class kon():
def __init__(self):
pass
def add(self):
con=7
self.bin=100
h=kon()
bin=h.bin
In one topic advised to use self. before variables but it did not work.
Maybe such variables must be in __init__ method.
You have to read docs. It will be very useful for you.
The instantiation operation (“calling” a class object) creates an empty object. Many classes like to create objects with instances customized to a specific initial state. Therefore a class may define a special method named init(), like this:
def __init__(self):
self.bin = 0
When a class defines an init() method, class instantiation automatically invokes init() for the newly-created class instance.
After this you can use this property in you object, to read or assign value.
Also, there is a difference between initialize properties in the class. From the docs:
class Dog:
kind = 'canine' # class variable shared by all instances
def __init__(self, name):
self.name = name # instance variable unique to each instance
This question already has answers here:
Adding a method to an existing object instance in Python
(19 answers)
Closed 6 years ago.
I have a Django model say:
class MyOperation(models.Model):
name = models.CharField(max_length=100)
def my_method(self):
pass
I want to be able to add, from a different Django app, a new method to this class.
I tried to do this from a different app module called custom.py:
from operations.models import MyOperation
def op_custom(test):
print "testing custom methods"
MyOperation.op_custom = op_custom
However this does not seems to work, in runtime the method does not exists.
Is this the way to modify the definition of a class from a different django application? Is there a better way to do it?
Thanks
The Right Way™ to do this is via a mixin:
class MyMixIn(object):
def op_custom(self):
print("foo")
class MyOperation(models.Model, MyMixIn):
def op_normal(self):
print("bar")
This has several advantages over monkey-patching in another method:
The mixin is in the class' method resolution order, so introspection works perfectly.
It is guaranteed to be defined on every instance of the class regardless of where it is instantiated since the class itself inherits from the mixin. Otherwise, you may end up with instances from before the monkey patch is applied where this method isn't there.
It provides an obvious place to add such methods in the future.
This question already has answers here:
Difference between #staticmethod and #classmethod
(35 answers)
Closed 9 years ago.
I have written a code like this,and they are all works for me,but what is the difference? which is better?
class Demo1(object):
def __init__(self):
self.attr = self._make_attr()
def _make_attr(self):
#skip...
return attr
class Demo2(object):
def __init__(self):
self.attr = self._make_attr()
#staticmethod
def _make_attr():
#skip...
return attr
If both are working it means that inside make_attr you are not using self.
Making it a regular non-static method only makes sense if the code could logically depend on the instance and only incidentally doesn't depend on it in the current implementation (but for example it could depend on the instance in a class derived from this class).
When it comes to functionality, #staticmethod doesn't really matter. It's value is semantic - you are telling yourself, or other coders, that even though this function belongs to the namespace of the class, it isn't tied to any specific instance. This kind of tagging can be very useful when refactoring the code or when looking for bugs.
In either, attr is a local variable and does not depend on anything in the class. The results are the same. Marking it as static gives you the benefit of knowing this, and being able to access it directly, such as Demo2._make_attr() without having to create and instance of the class.
If you want it to acces the class variable, you would reference it as self.attr. But if you're doing this, then Demo2._make_attr() can no longer be static.