Inherit private attribute from abstract class python3 - python-3.x

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?

Related

maximum recursion depth exceeded: abstract property inheritance in python

I am trying to define an abstract class with an abstract property that can then be inherited in a concrete class. But it is giving me maximum recursion depth exceeded.
Vechile is an abstract class and Car implements that class. The base class has a property called parking_ticket which I am keeping out of the __init__ of the abstract class and defining a property called parking_ticket to act as a getter and setter. Please help me to point out where is the mistake.
Abstract Class
"""
module string
"""
from abc import ABC, abstractmethod
from vehicle_type import VehicleType
from parking_ticket import ParkingTicket
class Vechile(ABC):
"""
class docstring
"""
#abstractmethod
def __init__(self, license_plate: str,
kind_of_vehicle: VehicleType) -> None:
self.plate_number = license_plate
self.vehicle_type = kind_of_vehicle
self.parking_ticket = None
#property
#abstractmethod
def parking_ticket(self):
pass
#parking_ticket.setter
#abstractmethod
def parking_ticket(self, parking_ticket: ParkingTicket):
pass
Concrete Class
from vehicle import Vechile
from vehicle_type import VehicleType
from parking_ticket import ParkingTicket
from datetime import datetime, timedelta
class Car(Vechile):
def __init__(self,
license_plate: str) -> None:
super().__init__(license_plate, VehicleType.CAR)
#property
def parking_ticket(self):
return self.parking_ticket
#parking_ticket.setter
def parking_ticket(self,
ticket: ParkingTicket):
self.parking_ticket = ticket
p_ticket = ParkingTicket(ticket_number="123",
plate_number="12345",
allocated_spot_id=10,
issued_at=datetime.utcnow(),
vaccated_at=datetime.utcnow() + timedelta(hours=5),
charges=50
)
c = Car('MH53TS7618')
c.parking_ticket = p_ticket
print(c)
found the answer for it. I was using the same variable name as the method name and instance variable. hence the run time exception was occuring.

How to access a class constant inside class Meta?

class MyClass(models.Model):
CONSTANT = "value"
...
class Meta:
# I want to Access CONSTANT here
I know a simple solution of hardcoding the "value" inside class Meta, but is there a way to access the outer class CONSTANT. I tried CONSTANT and MyClass.CONSTANT inside class Meta, but these two ways did not work.
class MyClass:
CONST = 'val from MyClass'
def __init__(self):
self.meta = self.Meta()
class Meta:
def __init__(self):
self.value = MyClass.CONST
if __name__ == '__main__':
my_class = MyClass()
print(my_class.meta.value)
# something like this

Is there a way for the child function that will inherit more than one parent function to access all of the parent's methods?

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())

Is it possible to have alternative inheritance in python3?

My goal:
class BaseClass1:
def f(self)
class BaseClass2:
def f(self)
class DerivedClass:
def g(self):
self.f() # this is either BaseClass1::f() or BaseClass2::f(), depending on instantiation
Where DerivedClass is can be instanced either:
class DerivedClass(BaseClass1)
or
class DerivedClass(BaseClass2)
I understand that this can solve the problem itself:
class UtilityClass1:
def f(self)
class UtilityClass2:
def f(self)
class DerivedClass:
def __init__(self, utilityInstance):
self.utility = utilityInstance
def g(self):
self.utility.f()
d = DerivedClass(UtilityClass1())
d = DerivedClass(UtilityClass2())
However, I specifically want to know, if there is another way, through inheritance (probably using some decorators, or whatever).
Just to wrap things up:
INPUT:
3 class definitions:
class BaseClass1
class BaseClass2
class DerivedClass
OUTPUT:
2 "merged" class instances:
d1 = DerivedClass(BaseClass1)
d2 = DerivedClass(BaseClass2)

Better way than pass the same argument among classes in Python

I have a question related to OOP but it should be implemented in Python.
I have a file user_inputs.py with all the user parameters.
In my main file, I have a function that is called first. This function is responsible to read all the user parameters and return a dictionary that will be used in the rest of the program.
My question is: what is the cleanest way to pass the user_parameters dictionary to all classes? I did it in 2 ways:
Method 1)
def read_user_parameters():
# code to open and read all parameters etc.
return user_parameters # returns a dictionary with all the user parameters
Class A():
def __init__(self, user_parameters):
self.user_parameters = user_parameters
Class B():
def __init__(self, user_parameters):
self.user_parameters = user_parameters
user_parameters = read_user_parameters()
object_A = A(user_parameters)
object_B = B(user_parameters)
I don't like this way because I have dozens of classes that need to pass this argument. So I thought to create a parent class with the user parameters:
Method 2)
Class User_parameters():
def __init__(self, user_parameters):
def read_user_parameters():
# code to open and read all parameters etc.
return user_parameters
Class A(User_parameters):
__init__(self, user_parameters):
super().__init__()
# self.user_parameters comes from the parent class now
Class B(User_parameters):
__init__(self, user_parameters):
super().__init__()
# self.user_parameters comes from the parent class now
object_A = A()
object_B = B()
I prefer method 2, however, when super() is initialized from Class A and Class B the function read_user_parameters() that reads the file will be called twice (multiply this by dozens of times). Is there a better solution than method 1 in which I call read_user_parameters() only once but doesn't need to pass the argument for all classes?
Thank you for your time.
Why not just have a single UserParameters class and two objects of the same class (Also class nameds are supposed to be camel-cases, not snake-cased)
#Single class for user parameters
class UserParameters:
def __init__(self, user_parameters):
self.user_parameters = user_parameters
def read_user_parameters(self):
# code to open and read all parameters etc.
return self.user_parameters
#Two objects
object_A = UserParameters("<params>")
object_B = UserParameters("<params>")

Resources