Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

typed python: using the classes' own type inside class definition [duplicate]

Tags:

The following code does not work as expected. Apparently, I cannot use the classes' own type inside class definition:

class Foo:     def __init__(self, key :str) -> None:         self.key = key      def __eq__(self, other :Foo) -> bool:         return self.key == other.key  print('should be true: ', Foo('abc') == Foo('abc')) print('should be false: ', Foo('abc') == Foo('def')) 

The result of running it is:

Traceback (most recent call last):   File "class_own_type.py", line 1, in <module>     class Foo:   File "class_own_type.py", line 5, in Foo     def __eq__(self, other :Foo) -> bool: NameError: name 'Foo' is not defined 

Also, checking the code with mypy returns:

class_own_type.py:5: error: Argument 1 of "__eq__" incompatible with supertype "object" 

How can I correct this code to be valid, both for Python and for mypy?

like image 324
macjan Avatar asked Mar 16 '17 22:03

macjan


People also ask

What is type class Python?

type is a metaclass, of which classes are instances. Just as an ordinary object is an instance of a class, any new-style class in Python, and thus any class in Python 3, is an instance of the type metaclass. In the above case: x is an instance of class Foo . Foo is an instance of the type metaclass.

How do you create a type in Python?

First, extract the class body as string. Second, create a class dictionary for the class namespace. Third, execute the class body to fill up the class dictionary. Finally, create a new instance of type using the above type() constructor.

How do you make a class dynamic in Python?

Python Code can be dynamically imported and classes can be dynamically created at run-time. Classes can be dynamically created using the type() function in Python. The type() function is used to return the type of the object. The above syntax returns the type of object.

What is types SimpleNamespace?

class types. SimpleNamespace. A simple object subclass that provides attribute access to its namespace, as well as a meaningful repr. Unlike object , with SimpleNamespace you can add and remove attributes.


1 Answers

The name Foo isn't bound yet, because the class itself has not yet been defined at the time that you try to use the name (remember: function arguments are evaluated at function definition time, not at function call time).

From Python 3.7+ you can postpone evaluation of annotations by adding this import at the top of the module:

from __future__ import annotations 

In Python 3.10 postponed evaluation will become the default behavior. For Python < 3.7, you can use string literals to delay evaluation of the type:

class Foo:     def __init__(self, key :str) -> None:         self.key = key      def __eq__(self, other: 'Foo') -> bool:         return self.key == other.key  print('should be true: ', Foo('abc') == Foo('abc')) print('should be false: ', Foo('abc') == Foo('def')) 
like image 122
wim Avatar answered Oct 05 '22 14:10

wim