Overload Parameter for Dict - python-3.x

this is my problem:
I have two classes. In the Student class, a dict is passed in the constructor. This dict contains a list of dict. How can I pass the elements from this list to the Course class?
The classes are updated with the dict.
The metaclass is for overloading the _update function which I use in the bouth classes. #singledispatchmethod is for this because I use two constructors. One for the data (individual parameters) and the others for the dict.
from functools import singledispatchmethod
class MetaObject(object):
def _update(self, newDict: dict):
for key, value in newDict.items():
setattr(self, key, value)
class Course(MetaObject):
_name: str
#singledispatchmethod
def __init__(self):
pass
#__init__.register
def _(self, name: str):
self._name = name
#__init__.register(dict)
def _(self, dict: dict):
self._update(dict)
def print(self):
print("name:", self._name)
class Student(MetaObject):
_name: str
_courses: list
#singledispatchmethod
def __init__(self):
pass
#__init__.register
def _(self, name: str, courses: list):
self._name = name
self._courses = courses
#__init__.register(dict)
def _(self, dictValue: dict):
self._update(dictValue)
def print(self):
print("Name:", self._name, "Couses:")
c: Course
for c in self._courses:
print(c)
course1 = Course("Data Structures")
course2 = Course("Computer Networks")
student = Student("Danish", [course1, course2])
std_info = {'_name': "Danish", '_courses': [{"_name": 'Data Structures'}, {"_name": 'Computer Networks'}]}
student = Student(std_info)
student.print()

Related

How do I convert a composite class into a dictionary?

I have a class called Large, which contains an instance of Small.
class Small:
s: str
def __init__(self):
self.s = "I am Small"
class Large:
small: Small
details: str
def __init__(self):
self.small = Small()
self.details = "Details???"
when I call the class and try to look at its dictionary, it looks broken
large = Large()
print(large.__dict__)
{'small': <__main__.Small object at 0x1110e2e50>, 'details': 'Details???'}
how do I force the small attribute to a dictionary also?
You can do this like:
>>> class Small:
def __init__(self):
self.s = "I am Small"
>>> class Large:
def __init__(self):
self.small = Small()
self.details = "Details???"
>>> def object_to_dict(instance):
output = {}
if not isinstance(instance, dict):
items = instance.__dict__.items()
else:
items = instance.items()
for key,value in items:
if isinstance(value, Small):
output[key] = object_to_dict(value.__dict__)
else:
output[key] = value
return output
>>> large = Large()
>>> large.littleSmall = Small()
>>> print(object_to_dict(large))
{'small': {'s': 'I am Small'}, 'details': 'Details???', 'littleSmall': {'s': 'I am Small'}}
But it only get __dict__ for a Small object if there is more classes you should add them in isinstance() function as tuple on second argument

Python: creating a dictionary: {int, class object} in a loop

I'd like to create a dictonary: {int, Class} in a loop, however the class object is being overriden.
I am pretty sure that this is a basic problem, but I am stuck
class Simple:
simpleDic = {
'name': {""},
'age': {1}}
def __init__(self, name, age):
self.simpleDic['name'] = name
self.simpleDic['age'] = age
def __str__(self):
return "{} {}\n".format(self.simpleDic['name'], self.simpleDic['age'])
def foo():
myDict = {}
for x in range(3):
myDict[x] = Simple('Name' + str(x), x)
print(('{}: {}\n'.format("Creating", myDict[x])))
for key in myDict:
print(('{}: {}\n'.format("Printing" + str(key), myDict[key])))
#### Main program here ####
foo()
The output is as follows:
You're problem is on the last print
You're printing myDict[x] when you should print myDict[key]
x contains the last value from the first iteration, so you're practically printing the same key all over
Following your question in this comments:
class Simple:
def __init__(self, name, age):
self.simpleDic = {"name": name, "age": age}
def __str__(self):
return "{} {}\n".format(self.simpleDic['name'], self.simpleDic['age'])
def __repr__(self):
return "{} {}\n".format(self.simpleDic['name'], self.simpleDic['age'])
def foo():
myDict = {}
for x in range(3):
myDict[x] = Simple('Name' + str(x), x)
print(('{}: {}\n'.format("Creating", myDict[x])))
print(myDict)

Python: for multiple properties use one getter and setter method

I have created a class that has multiple properties. I want to use one function for the getter method and the second one for the setter method.
class person:
def __init__(self, fname, lname, city, state):
# make all attributes as private
self._fname = fname
self._lname = lname
self._city = city
self._state = state
#property # get method
def fname(self):
return self._fname
#fname.setter # set method
def fname(self,fname):
self._fname = fname
#property
def lname(self):
return self._lname
#lname.setter
def lname(self,lname):
self._lname = lname
#property
def city(self):
return self._city
#city.setter
def city(self, city):
self._city = city
#property
def state(self):
return self._state
#state.setter
def state(self, state):
self._state = state
How to use all properties for one get methods and one set method?
e.g.:
def get(self):
return self._attr
def set(self,value):
self._attr = value
class person:
def __set_name__(self, name):
self.name = name
def __get__(self, obj, type=None) -> object:
return obj.__dict__.get(self.name)
def __set__(self, obj, value) -> None:
obj.__dict__[self.name] = value
my_value = person
my_values.fname = 'Shivam'
my_values.lname = 'Gupta'
print(my_values.fname) #--> Shivam
print(my_values.lname) #--> Gupta

Implementing a python class

I am working on a personal project and I am having trouble implementing this following part.
Implementing a Menu Class.
This class will make use of MenuItem objects.
This class represents the restaurant menu which contains 4 different categories of menu item diners can order from.
This class will have a single class(or static) variable:
Menu_Item_types: a list containing 4 strings representing the 4 possible types of menu items.: Drink, appetizer, entree, dessert.
This class will use the following instance attribute:
List item
self.menuItemDrinkList: list of all drink list
self.menuItemAppetizerList: list of all appetizer list
self.menuItemEntreeList: a list of all entree list
self.menuItemDessertList: a list of all the dessert list
Below is the menuItem object
class MenuItem:
def __init__(self, name=None, types=None, price=None, description=None):
self.name = name
self.types = types
self.price = price
self.description = description
def setName(self, name):
self.name = name
def getName(self):
return self.name
def setTypes(self, types):
self.types = types
def getTypes(self):
return self.types
def setPrice(self, price):
self.price = price
def getPrice(self):
return self.price
def setDescription(self, description):
self.description = description
def getDescription(self):
return self.description
def __str__(self):
return "{} ({}): ${}, {}".format(self.name, self.types, self.price, self.description)
If I understand you correctly you are looking for setters and getters properties. Here is the way how you do it in Python.
You can learn more about properties here:
class MenuItem:
def __init__(self, name=None, types=None, price=None, description=None):
self._name = name
self._types = types
self._price = price
self._description = description
#property
def name(self):
return self._name
#name.setter
def name(self, name):
self._name = name
#property
def types(self):
return self._types
#types.setter
def types(self, types):
self._types = types
#property
def price(self):
return self._price
#price.setter
def price(self, price):
self._price = price
#property
def description(self):
return self._description
#description.setter
def description(self, description):
self._description = description
def __str__(self):
return "{} ({}): ${}, {}".format(
self._name, self._types, self._price, self._description
)
menu_item = MenuItem("pizza", "entry", 10)
print(menu_item)
menu_item.price = 20
menu_item.description = "Delicious"
print(menu_item)
output:
pizza (entry): $10, None
pizza (entry): $20, Delicious
Please notice:
In python you don't call properties with getXxx or setXxx, you just use regular names and decoreate methods with #property and #xxx.setter
You should have #property before #setter.
Setter must start with the property name
In order to escape recursion, name your internal
attributes with _ (_name). If you will not do it you will have a
"RecursionError: maximum recursion depth exceeded in comparison"
because setter will call itself in the loop.

Circular dependency in the class constructor

I have the following class:
class CustomDictionary(dict):
def __init__(self, val, *args, **kwargs):
self.wk = val
super(dict, self).__init__()
def __setattr__(self, key, value):
if key in self.wk:
raise Exception("Wrong key", "")
key = key.replace(" ", "_")
self.__dict__[key] = value
def main():
wrong_keys = ("r23", "fwfew", "s43t")
dictionary = CustomDictionary(wrong_keys)
dictionary["a1"] = 1
As you can see, I create the attribute wk in the constructor. But I have __setattr__ function, in which I work with attribute wk. However, CustomDictionary object has no attribute wk.
__setattr__ is a pain that way, because it is called for every assignment to an instance member. Probably the easiest fix for your situation is to define an empty wk before __init__:
class CustomDictionary(dict):
wk = []
def __init__(self, val, *args, **kwargs):
self.wk = val
...

Resources