I am getting an error when making a third class that inherits the first two classes' attributes. The first class's function will be go through but when accessing the second class's function I am gettting an error:
class3' object has no attribute 'othernum
Here is the code:
class class1():
def __init__(self):
self.number = 10000
def getNum(self):
return self.number
class class2():
def __init__(self):
self.othernum = 1111
def displaynum(self):
return self.othernum
class class3(class1, class2):
pass
newperson = class3()
print(newperson.getNum())
print(newperson.displaynum())
Found the answer.
class class3(class1, class2):
def __init__(self):
class1.__init__(self)
class2.__init__(self)
The answer presented by #Ishaan Sathaye is indeed correct. But be aware that there are several mechanisms for initializing base classes in a multiple inheritance hierarchy. See Calling parent class init with multiple inheritance, what's the right way?, in particular the section with heading All base classes are designed for cooperative inheritance.
So, if your 3 classes were designed for cooperative inheritance, we would have:
class class1():
def __init__(self):
super().__init__()
self.number = 10000
def getNum(self):
return self.number
class class2():
def __init__(self):
super().__init__()
self.othernum = 1111
def displaynum(self):
return self.othernum
class class3(class1, class2):
def __init__(self):
super().__init__()
newperson = class3()
print(newperson.getNum())
print(newperson.displaynum())
main.py
...
person = cPerson("xyz", "ozp")
...
person.set_name("somename")
...
csystem = cSystem()
...
cperson.py
class cPerson:
def __init__(self, addr, client):
self.addr = addr
self.client = client
self.name = None
def set_name(self, name):
self.name = name
csystem.py
from cperson import cPerson
class cSystem(cPerson):
def __init__(self):
print(self.name)
Can i access self.name from the parent class in this way? I get the error message:
AttributeError: 'cSystem' object has no attribute 'name'
I do not want to initialize from the csystem class, i want the current value from the instance variable set as shown in the main program.
I am not entirely sure what you want the end result to be.
In any case is this what you are looking for?
class cPerson:
name = None
def __init__(self, addr, client):
self.addr = addr
self.client = client
#classmethod
def set_name(cls, value):
cls.name = value
class cSystem(cPerson):
def __init__(self, addr, client):
super().__init__(addr, client)
print(self.name)
person = cPerson("xyz", "ozp")
person.set_name('Jake')
csystem = cSystem("xyz", "ozp")
The above code returns 'Jake'.
A class method is a method which is bound to the class and not the object of the class. They have the access to the state of the class as it takes a class parameter that points to the class and not the object instance.
Is this what you were looking for? If not can you explain the problem in a bit more detail?
I have the following code:
class Parent():
def __init__(self):
self.variable1 = self.method1()
self.variable2 = self.method2()
self.variable3 = self.method3()
self.variable4 = self.method4()
#.........(for example I have 100 variables here)
def method1(self):
return 100
def method2(self):
return 200
def method3(self):
return 300
def method4(self):
return 400
class Third():
def __init__(self):
a = 1
def call(self):
value = self.variable3 + 1
return value
class Child(Parent):
def __init__(self):
super().__init__()
self.getanswer = self.method11()
def method11(self):
value_count = Third().call()
return value_count
obj = Child()
It throwed the following Error:
AttributeError: 'Third' object has no attribute 'variable3'
Here I wanted to send all the values of parent to Third Class through Child class. How can I achieve it? I know that I can pass Parent class variables seperately in directly as a parameter in the class Third as following:
value_count = Third(self.variable3).call()
and change the Third Class constructor accordingly. But I don't want to do it as my Parent class has some time taking operations to do.
Also I don't want to make class Third as child to the class Parent.
So How can I recognize the Parent class variables(variable1, variable2, variable3, variable4, ....) in Third Class through Child Class ?
I have an abstract class that i will use as template to implement different kind of subclasses.
I want to define some attributes/methods that are mandatory to all subclasses. For example
class BlockModel(ABC):
def __init__(self, position):
self.__position = position
self.__lives = None
self.__hitbox = None
#property
def lives(self):
return self.__lives
#lives.setter
def lives(self, lives):
self.__lives = lives
#property
def hitbox(self):
return self.__hitbox
#hitbox.setter
def hitbox(self, hitbox):
self.__hitbox = hitbox
#abstractmethod
def method1(self)
#some abstract methods
#abstractmethod
def method2(self)
#some abstract methods
When i create a subclass, for example
class Block1(BlockModel):
def __init__(self,position_):
super().__init__(position_)
self.__lives=1
self.__hitbox = pygame.Rect(self.__position['x'],
self.__position['y'],
5,
5)
#Implement abstract methods
The second class doesn't inherit the attributes __position, __lives, __hitbox, but the public ones without the underscores (i know that there are no real private attributes/methods in python). There s a way too keep them private(with underscores) in the subclass too?
I'm trying to dynamically create a class using type() and assign an __init__ constructor which calls super().__init__(...); however, when super() gets called I receive the following error:
TypeError: super(type, obj): obj must be an instance or subtype of type
Here is my code:
class Item():
def __init__(self, name, description, cost, **kwargs):
self.name = name
self.description = description
self.cost = cost
self.kwargs = kwargs
class ItemBase(Item):
def __init__(self, name, description, cost):
super().__init__(name, description, cost)
def __constructor__(self, n, d, c):
super().__init__(name=n, description=d, cost=c)
item = type('Item1', (ItemBase,), {'__init__':__constructor__})
item_instance = item('MyName', 'MyDescription', 'MyCost')
Why is super() inside the __constructor__ method not understanding the object parameter; and how do I fix it?
Solution 1: Using cls = type('ClassName', ...)
Note the solution of sadmicrowave creates an infinite loop if the dynamically-created class gets inherited as self.__class__ will correspond to the child class.
An alternative way which do not have this issue is to assigns __init__ after creating the class, such as the class can be linked explicitly through closure. Example:
# Base class
class A():
def __init__(self):
print('A')
# Dynamically created class
B = type('B', (A,), {})
def __init__(self):
print('B')
super(B, self).__init__()
B.__init__ = __init__
# Child class
class C(B):
def __init__(self):
print('C')
super().__init__()
C() # print C, B, A
Solution 2: Using MyClass.__name__ = 'ClassName'
An alternative way to dynamically create class is to define a class inside the function, then reassign the __name__ and __qualname__ attributes:
class A:
def __init__(self):
print(A.__name__)
def make_class(name, base):
class Child(base):
def __init__(self):
print(Child.__name__)
super().__init__()
Child.__name__ = name
Child.__qualname__ = name
return Child
B = make_class('B', A)
class C(B):
def __init__(self):
print(C.__name__)
super().__init__()
C() # Display C B A
Here is how I solved the issue. I reference the type() method to dynamically instantiate a class with variable references as such:
def __constructor__(self, n, d, c, h):
# initialize super of class type
super(self.__class__, self).__init__(name=n, description=d, cost=c, hp=h)
# create the object class dynamically, utilizing __constructor__ for __init__ method
item = type(item_name, (eval("{}.{}".format(name,row[1].value)),), {'__init__':__constructor__})
# add new object to the global _objects object to be used throughout the world
self._objects[ item_name ] = item(row[0].value, row[2].value, row[3].value, row[4].value)
There may be a better way to accomplish this, but I needed a fix and this is what I came up with... use it if you can.