Inheriting properties of a separate class in Python - python

I am instantiating a class inside another one:
class A(F):
def __init__(self):
return
b = B()
Class B also inherits class F:
class B(F):
def __init__(self):
return
There are properties of F which have been defined in class A, which I need to access inside class B. (a MySQL connection and a logging handler.)
I would like B to have the properties which have been set to F, when they were instantiated initially in A, so I can use the logging/mysql handlers inside B without re-instantiating them.
How can I go about this? Sorry if the question is unclear.

Put the stuff you want to share in F and both A and B will be able to share it. Eg
class F(object):
def useful(self):
pass
class A(F):
def something(self):
self.useful()
class B(F):
def something_else(self):
self.useful()

Related

How can i separate methods of a class in separate files?

Let's say we have this class:
Class example:
def __init__(self):
self.var = 23
How can i access this variable within a function in another file by importing it in the main file?
def my_func():
pass
In fact i want the "my_func()" to be a method of the "example" class but in a separate file.
The idea is to split your class into two classes that have no data of their own—only methods—so although you inherit them, you never have to call super() on them. This classes are called "mixins"
_example.py
class Mixin:
def my_func(self):
print(self._b)
example.py
import _example
class Example(_example.Mixin):
def __init__(self):
self._a = 1
self._b = 2
self._c = 3
Now you can do:
ex = Example()
ex.my_func() # This will print "2" on console.
You can check different aproaches here

how to know from which class instance a function is called to access the instance attributes

I want to access an attribute of the class instance that called a function :
for example:
class A:
def a(self):
return B.q
class B:
q=0
def b(self):
M=A()
return M.a()
c=B()
c.q = 6
print(c.b())
the output will be 0 but I want it to print the q attribute of the instance c of the class B which has the value 6
Pass the instance as a parameter.
class A:
def a(self, b):
return b.q
class B:
q=0
def b(self):
M=A()
return M.a(self)
c=B()
c.q = 6
print(c.b())
This appears to be very bad program design. What are you trying to accomplish with this?
You have a class attribute and an instance attribute -- in that class -- of the same name, q. This makes your code difficult to follow and to maintain.
You have method B.b instantiate an instance of class A. You immediately call A.a, which has been assigned the questionable task of returning an instance attribute from and object of class B.
Clean up your design.
Use init appropriately for each class.
Design your class methods to work appropriately with the characteristics of instances of that class. Your question strongly suggests that your design is not yet clean in your mind, nor in code.
define an init method so that you can work with the instance attributes instead of the class variable
class A:
def a(self):
return B.q
class B:
def __init__(self):
self.q = 0
def b(self):
M=A()
return M.a()
c=B()
c.q = 6
print(c.b())

Can a specific base class object be set as the base object of an inherited class/object in python?

I have a class A and a class B derived from A.
After creating an instance of class A with many operations performed, I now want to serialize that specific object. Let's call that object A_instance.
When initializing class B, how can I tell B that it's base object should be A_instance?
Within B's init i want to decide whether it should normally execute super().__init__(...) or setting the base object directly to A_instance.
Here is a code example which makes my question hopefully clear:
class A():
def __init__(self, a=1):
self.a = a
self.message = "Hello, I'm class A"
myA = A(15)
class B(A):
def __init__(self, b=2, my_base=None):
if my_base:
# what should i code here? maybe someting like super().super_object = my_base
pass
else:
super(B, self).__init__()
self.b = b
self.message = "Hello, I'm class B inherited from A"
#Then the above code should result in something like:
myB = B(my_base=myA)
assert myB.a == myA.a
A similar if not even the same question for C++ can be found here:
set the base object of derived object?

python dynamic multiple inheritance __init__

I am trying to write a plugin environment where I need to do multiple inheritances on an unknown number of classes. Therefore, I have opted to use the type class creation:
class A(object):
def __init__(self,s):
self.a="a"
def testA(self,x):
print(x)
class B(object):
def __init__(self,s):
self.b="b"
def testA(self,x):
print(x)
C = type('C', (A,B), {})
x= C("test")
print x.b
When I run the above code, I get the error:
AttributeError: 'C' object has no attribute 'b'
This is because only the init for class A is being run when the instance for class C is initialized. My question is how can I get the class C to have both the init for class A as well as the init for class B to run when an instance of class C is initialized. I do realize that if I had class C like the following it would work:
class C(A,B):
def __init__(self,s):
A.__init__(self,s)
B.__init__(self,s)
However, given that I need to have a dynamic list of classes inherited this will not work.
It seems you're using python 2 so I'm using this old python 2 super() syntax where you have to specify the class and the instance, although it would work in python 3 as well. In python 3 you could also use the shorter super() form without parameters.
For multiple inheritance to work is important that the grandparent class __init__ signature matches the signature of all siblings for that method. To do that, define a common parent class (MyParent in this example) whose __init__ has the same parameter list as all the childs. It will take care of calling the object's __init__ that doesn't take any parameter, for us.
from __future__ import print_function
class MyParent(object):
def __init__(self, s):
super(MyParent, self).__init__()
class A(MyParent):
def __init__(self, s):
self.a = "a"
super(A, self).__init__(s)
def testA(self, x):
print(x)
class B(MyParent):
def __init__(self, s):
self.b = "b"
super(B, self).__init__(s)
def testA(self,x):
print(x)
C = type('C', (A, B), {})
x = C("test")
print(x.b)
You can define as many children to MyParent as you want, and then all __init__ methods will be called, provided you used super() correctly.

How to write better way to python inheritance?

I have written this,
class Sp():
def __init__(self):
self.price = 1
class A(Sp):
def __init__(self):
super(A, self).__init__()
self.test = True
class B(A):
pass
class C(A):
pass
class D(A):
"""In this class I don't want to inherit Sp class, but need A class"""
def __init__(self):
super(D, self).__init__()
self.me = 'ok'
self.list_ = [Sp()]
Sp is the Parent class for A. And I'm using A class in B,C and D, But D don't need Sp inheritance instead it needs Sp instance object inside D(Please look into D class). I want to stop Sp inheritance in D, is there any good way to write this ?
You can't inherit from A without inheriting from Sp if A itself inherits from Sp. You could try to work around it though, by making A inherit from two classes, one of which implements the non-Sp behaviors (say, call it Abits), and Sp (class A(Abits, Sp):). Then have B and C inherit A, while D inherits solely from Abits.
If A doesn't need to be created independently, you could just make A not inherit from Sp at all, and have B and C inherit from both A and Sp (class B(A, Sp):), while D only inherits from A, which saves the need for a separate Abits.
Lastly, you might consider composition. Have D not inherit from anything, just contain an instance of A. Then use the __getattr__ special method to get attributes from A when they're not defined on D:
class D(object): # Explicitly inheriting from object not needed on Py3
def __init__(self, ...):
self.a = A(...)
def __getattr__(self, name):
# Only called when attribute "name" doesn't exist on instance of D
return getattr(self.a, name)
You might also need to use __setattr__ if you need to mutate the A instance. This is trickier (because __setattr__ is called unconditionally, not just when an attribute doesn't exist), but there are plenty of examples of using it available if you search.

Categories