Home > Back-end >  Creating a Class and Objects
Creating a Class and Objects

Time:11-28

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)}
  • Related