4

I have the next structure of classes:

class Root:
    @dataclass
    class Leaf:
        pass

    @dataclass
    class Node:
        leaf: Leaf

The problem is PyCharm doesn't see Leaf class, I also tried to specify it as leaf: Root.Leaf and even 'Root'.Leaf... There was same result.
How to declare a field type in the inner class if the type is another inner class? Is it possible in python?
P.S. I can make the Leaf class an inner of the Node class but I am interested in my example.

Denis Sologub
  • 7,277
  • 11
  • 56
  • 123
  • Did you try `'Root.Leaf'`? – Green Cloak Guy Mar 18 '21 at 15:13
  • @GreenCloakGuy yes, however it doesn’t work too. PyCharm still highlights it as error – Denis Sologub Mar 18 '21 at 15:14
  • 2
    The issue is unrelated to dataclasses, and thus seems to be a duplicate of [Python - reference inner class from other inner class](https://stackoverflow.com/questions/42185472/python-reference-inner-class-from-other-inner-class) – Jan Christoph Terasa Mar 18 '21 at 15:18
  • @JanChristophTerasa it's little another question, how to initialize a field by an object of another inner class. I ask about type annotations. Seems it's impossible in python – Denis Sologub Mar 18 '21 at 15:21
  • 2
    Using nested classes in Python is rarely a good idea. They don't do anything special (unlike in, say, Java), and they give you namespace headaches like this one. – user2357112 Mar 18 '21 at 15:23
  • 1
    Likely your design is a bit backwards, you probably want top-level class definition of `Node`, and both `Leaf` and `Root` are special cases of `Node`s (inheritance). But do you even need special classes for that? I think you should post the problem you are trying to solve. I understand the sentiment of putting classes inside of classes for namespacing reasons (since Python does not have a dedicated namespace construct), but you can create namespaces by using modules (files) as well. – Jan Christoph Terasa Mar 18 '21 at 15:25
  • 2
    @Шах Annotations are just additions for the programmer/reader without any semantics for the interpreter, i.e. they get completely, 100% ignored. Your code also does not work on a functional level, not only on level of the annotations. What you are trying to do is not possible. – Jan Christoph Terasa Mar 18 '21 at 15:27
  • @JanChristophTerasa, I have another class structure that's similar to this, just I can't post a real business logic so created that sample – Denis Sologub Mar 18 '21 at 15:29
  • @JanChristophTerasa I see, thank you for answer. I just wanted to be sure it's really impossible – Denis Sologub Mar 18 '21 at 15:30
  • 1
    You could declare `global Leaf` as your first statement after `class Root:` but IMO that's a code smell and defeats your purpose for an inner class. That and your linter will probably hate you. – Axe319 Mar 18 '21 at 15:55
  • 1
    @Axe319 thank you for answer... You are right that's not elegant solution that I looked for. I've decided to keep a plain structure without inner classes (using of namespace `internal`) – Denis Sologub Mar 18 '21 at 16:00

0 Answers0