0

I am new to Python. I have a function like below which returns a dictionary.

def get_my_class_object(self, input):
    return {
            "foo": {"test": {}}, // this is hard-coded
            "var": "FIRST" // real code computes var using the input
        }

I'd like to define a class for the return type so I can enable the type using Pyre. What is the best practice to create a python class for above structure?

I tried below class and changed the function signature to return MyClassObject.

class MyClassObject(NamedTuple):
    foo: Dict
    var: str
def get_my_class_object(self, input) -> MyClassObject:
// create MyClassObject from input and return the object

But Dict is not allowed by Pyre as it is too generic. I can't change "foo": {"test": {}} due to backward compatibility.

Stevoisiak
  • 23,794
  • 27
  • 122
  • 225
user800799
  • 2,883
  • 7
  • 31
  • 36

1 Answers1

2

There are a few things you might be able to do in this case. Without any context, it is quite hard to know what might be best for you.

But, using a more specific type-hint might work:

Here, instead of a NamedTuple, it might also be best to use a DataClass

@dataclass
class MyData:
    foo: dict[str, dict]
    var: str

Here, foo is typed as dict[str, dict] which may be specific enough for Pyre. If you know what the type of the "innermost" dictionary should be, you can type-hint that here too. For example, let's say the innermost dictionary will eventually be used to map a string to an int, you could type-hint it as:

dict[str, dict[str, int]]

It may also be more clear to use type aliases. Check out the python documentation for more info, but that could look something like:

# Defining type aliases
TestData = dict[str, int]  # Here I'm assuming this inner dictionary maps strings to ints
Test = dict[str, TestData]


@dataclass
class MyData:
    foo: Test  # here we can just use the alias to make the code cleaner
    var: str

You might need to change the names of these to better fit your purpose.

Also note, I'm using python 3.9+ syntax for type-hinting, if you are using a lower version, you'll need to import the Dict type from the typing module.

James Ansley
  • 49
  • 1
  • 3
  • Thanks for comment. If `foo` is always hard-coded with dictionary `{"test": {}}`, what is the best way to init `foo` ? – user800799 Apr 13 '22 at 05:55
  • 1
    Using a dataclass, you could do something like: `foo: Test = field(default_factory=lambda: {"test": {}})` Check out the [field documentation](https://docs.python.org/3/library/dataclasses.html#dataclasses.field) However, at this point, it might be easiest to use a regular class with an `__init__` method that sets the value. In _most_ cases, classes are cheap – if they make things easier, don't be afraid to use them. – James Ansley Apr 13 '22 at 06:33