1

This is not possible:

from typing import Union

def make_an_object(cls: type):
    """Returns an object constructed based on information about cls"""

class Number:
    def __init__(self, num: Union[float, int, Number]):
        if isinstance(num, Number):
            num = num.num
        self.num = num

    foo = make_an_object(__class__)

Of course, one could use __class__ for the isinstance. For the type annotations I can use "Number" (but I'd prefer to be able to use the type itself!). And for the make_an_object... well I don't know.

Is there a way to reference the class you're making in the class itself (recursion-style)?

Notes:

  • The example above is just an example, not the problem I'm trying to solve
  • One can achieve the reference problem with subclassing, but looking for a simpler solution.
thorwhalen
  • 1,920
  • 14
  • 26
  • Put `"Number"` in quotes in the type hint. Use `self.__class__` in the `isinstance()` check. – Brad Solomon Mar 03 '21 at 20:11
  • Import annotations: `from __future__ import annotations`. – Olvin Roght Mar 03 '21 at 20:15
  • You could use `from __future__ import annotations` for python 3.7-3.9. Use strings is also an option – NobbyNobbs Mar 03 '21 at 20:16
  • @NobbyNobbs, for python 3.9 also required. [PEP 563](https://www.python.org/dev/peps/pep-0563/#implementation) – Olvin Roght Mar 03 '21 at 20:16
  • @OlvinRoght oh, thx, probably it's phantom memories :) – NobbyNobbs Mar 03 '21 at 20:22
  • Hm... I guess my notes wasn't enough. It's not the "use in annotations" problem I'm trying to solve, but the problem mentioned in title. Referencing the class in the body (but not inside method). Say, for example, that I had some function, that took a class and returned an object. In the body of the class, I couldn't say `foo = make_a_method(__class__)`, because at that level, I don't have access to this `__class__`. – thorwhalen Mar 04 '21 at 00:09
  • I've edited the question so that the example code doesn't (hopefully) have a way out that side steps the actual question. – thorwhalen Mar 04 '21 at 00:14
  • There are 3 `Number` references; the duplicate handles the type hint. The reference in `__init__` works because by that time `Number` has been set as a global. The third, inside the class statement, doesn't work because `Number` doesn't exist yet. Solutions are to use a class decorator, assign to `Number.foo` after creating the class or to use a descriptor ([`__get__(None, Number)` is called on it](https://docs.python.org/3/reference/datamodel.html#object.__get__)). – Martijn Pieters Mar 04 '21 at 16:10

0 Answers0