-2

I have, for example, this class:

from dataclasses import dataclass

@dataclass
class Example:
    name: str = "Hello"
    size: int = 10

I want to be able to return a dictionary of this class without calling a to_dict function, dict or dataclasses.asdict each time I instantiate, like:

e = Example()
print(e)

{'name': 'Hello', 'size': 5}

What I have tried and did not work is ineriting from dict and callint dict.init inside Example's init, it seems to not recognize the name and size

Is there a nice solution to this?

Editing: my goal is that type(e) will be dict and not str, returning the dict from init is not possible, also, the keys and values should be obtained dynamically, and the values for name and size might change depending on the instantiations

  • Does this answer your question? [How to print instances of a class using print()?](https://stackoverflow.com/questions/1535327/how-to-print-instances-of-a-class-using-print) – AlexisG Mar 01 '22 at 07:49
  • @AlexisG No, maybe I was a little unclear, I have edited my question – user17319990 Mar 01 '22 at 08:25
  • @user17319990. `print` can't return a `dict` but the string representation of a `dict`. It's what my solution does. – Corralien Mar 01 '22 at 08:27
  • @user17319990 Yes, the print was a bad example of mine, i just want to return a dict of the class when i instantiate it, i have read about __new__ but i cant access the attributes from there. – user17319990 Mar 01 '22 at 08:33
  • @user17319990 If it's a bad example, why not [edit](https://stackoverflow.com/posts/71305181/edit) it out? changing the behavior of `print` is a *very* bad practice, and I don't know anyone that would recommend going down that route. The purpose of `print(e)` mutating the type of `e` is very doubtful thing. I would suggest spending time composing exactly the type of problem you're having. – rv.kvetch Mar 01 '22 at 16:01

3 Answers3

2

python class can provide a specific method to create a string representation:

def __str__(self):

Same as toString() java method.

Grunnpi
  • 92
  • 6
1

Override __str__ method:

from dataclasses import dataclass

@dataclass
class Example:
    name: str = "Hello"
    size: int = 10

    def __str__(self):
        return repr(self.__dict__)

e = Example()
print(e)  # Use __str__ method

Output:

{'name': 'Hello', 'size': 10}
Corralien
  • 109,409
  • 8
  • 28
  • 52
  • Thank you!, but i meant that the the type of e will be dict and not Example. Kind of returning a the __dict__ from the __init__ even that its not possible to return a value from __init__ – user17319990 Mar 01 '22 at 08:19
  • @user17319990 I think you need to spend a good amount of time figuring out exactly what *kind* of question you want to ask. Ensuring that `e` is type dict instead of Example is very confusing, and not likely to be possibly without calling a method like `asdict`. What *exactly* are you trying to achieve? As in, what is your use case? The `str()` method can convert to a string that looks like a dict, but if you want a dict to begin with, just use `e = {...}` and no need to bother with a dataclass at all. – rv.kvetch Mar 01 '22 at 15:56
-1

Here is a solution by using __new__

from dataclasses import dataclass

@dataclass
class Example:
    name: str
    size: int

    def __init__(self, name, size):
        self.name = name
        self.size = size

    def __new__(cls, *args, **kwargs):
        return kwargs

e = Example(**{"name":"Hello", "size":10})
print(e)

>>>> out :
>>>> {'name': 'Hello', 'size': 10}
AlexisG
  • 2,476
  • 3
  • 11
  • 25
  • Thanks, I have tried this as well, but 1. The keys are not obtained dynamicly, in this example this might be ok but in reality i have many big dataclasses 2. If I need to create new instance of Example (like e2) with different values for name or size, I cant (from my understanding this is because the __new__ is called before the __init__) – user17319990 Mar 01 '22 at 08:56
  • I've edited my answer and tried to meet your criteria – AlexisG Mar 01 '22 at 09:03
  • Still a bit off, Example clas should be called like e = Example() and i dont want to create the __init__ and writing the name and size there by myself. Im starting to think that it might be impossible but thank you anyway! – user17319990 Mar 01 '22 at 11:32
  • Ho to you initialize the values in your dataclasses ? – AlexisG Mar 01 '22 at 12:26
  • Example() for {'name': 'Hello', 'size': 10}, Example(size=12) for {'name': 'Hello', 'size': 12}. The values for name and size might change, but they can still remain Hello and 10 if I do not set otherwise. The class itself looks like it is shown in the question itself. Is that what you meant in your question? – user17319990 Mar 01 '22 at 14:19
  • i'm confused because creating an `__init__` defeats the whole purpose of using a `@dataclass`. Add on `__new__` and maybe a `repr=False` and it's at this point you realize that the entire purpose of dataclasses is completely missed. – rv.kvetch Mar 01 '22 at 15:59