I got an assignment. I have to create a class with objects. For example, the class Student. In this class I have to create certain students and then I have to assign these students to a set.
class Students:
def __init__(self, name, age):
self.name = name
self.age = age
def show_info(self):
return "'{}': {}".format(self.name, self.age)
def __str__(self):
return self.show_info()
Mark = Students(name="Mark", age=21)
Lisa = Students(name="Lisa", age=19)
So my question is how do I add these Objects(Mark,Lisa) to a set(). I'd be grateful if someone can give me some hints.
CodePudding user response:
Assuming you want the class instances Mark
and Lisa
themselves to be added to a set, a simple way in Python 3 is to make use of dataclasses -- which are essentially just regular classes under the hood -- and pass the unsafe_hash
parameter to the decorator, so that a __hash__
method is automatically generated for us, as shown below.
from dataclasses import dataclass
@dataclass(unsafe_hash=True)
class Student:
name: str
age: int
def show_info(self):
return "'{}': {}".format(self.name, self.age)
def __str__(self):
return self.show_info()
Mark = Student(name="Mark", age=21)
Lisa = Student(name="Lisa", age=19)
my_set = {Mark, Lisa}
print(my_set)
# If you want to customize how `Student` objects are displayed, implement
# a __repr__ instead of __str__, or just copy the implementation directly.
Student.__repr__ = Student.__str__
print(my_set)
Output:
{Student(name='Lisa', age=19), Student(name='Mark', age=21)}
{'Lisa': 19, 'Mark': 21}
If you want to add the instances attributes to a set instead, you can convert each instance to a tuple
of its attributes and pass it into the set
constructor instead, since tuples are immutable objects and are thus hashable. This is actually a great use-case for the astuple
helper function which is exported by the dataclasses
module.
from dataclasses import dataclass, astuple
@dataclass
class Student:
name: str
age: int
Mark = Student(name="Mark", age=21)
Lisa = Student(name="Lisa", age=19)
my_set = {astuple(Mark), astuple(Lisa)}
print(my_set)
Output:
{('Lisa', 19), ('Mark', 21)}
A simplification of the above concept is to use typing.NamedTuple
instead of the dataclass approach. This allows you to retain the type hinting support and the ability to pass keyword arguments to the constructor method as in the original example, but also makes each class instance inherently hashable, since named tuples are essentially tuples
under the hood. An example usage of NamedTuple
is shown below:
from typing import NamedTuple
class Student(NamedTuple):
name: str
age: int
Mark = Student(name="Mark", age=21)
Lisa = Student(name="Lisa", age=19)
my_set = {Mark, Lisa}
print(my_set)
Output:
{Student(name='Lisa', age=19), Student(name='Mark', age=21)}