Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python 3.6 types: Using variable before assignment [duplicate]

New way of type/hinting/assignments is cool, but I don't know how to make such a simple thing work:

class MyContainer:
    def addMyItem(self, item:MyItem):
        pass

class MyItem:
    def __init__(self, container:MyContainer):
        pass

It throw an error: Using variable 'MyItem' before assignment. The best but super ugly workaround I found so far is this:

class MyContainer:
    def addMyItem(self, untypeditem):
        item:MyItem=untypeditem
        pass

class MyItem:
    def __init__(self, container:MyContainer):
        pass

Please tell me that language with #1 principle Beautiful is better than ugly has something better to solve this common typing issue

like image 975
Philipp Munin Avatar asked May 23 '18 14:05

Philipp Munin


People also ask

Does Python enforce type hints?

Python will always remain a dynamically typed language. However, PEP 484 introduced type hints, which make it possible to also do static type checking of Python code. Unlike how types work in most other statically typed languages, type hints by themselves don't cause Python to enforce types.

How do you write a hint variable in Python?

Here's how you can add type hints to our function: Add a colon and a data type after each function parameter. Add an arrow ( -> ) and a data type after the function to specify the return data type.

What is type hinting in Python?

Type hinting is a formal solution to statically indicate the type of a value within your Python code. It was specified in PEP 484 and introduced in Python 3.5.

What is MYPY?

“Mypy is an optional static type checker for Python that aims to combine the benefits of dynamic (or 'duck') typing and static typing. Mypy combines the expressive power and convenience of Python with a powerful type system and compile-time type checking.” A little background on the Mypy project.


1 Answers

Forward references are just strings referring to the name (as it is visible in the module).

class MyContainer:
    def addMyItem(self, item: 'MyItem'):
        pass

class MyItem:
    def __init__(self, container: 'MyContainer'):
        pass

If you need to import the name from somewhere else (and you only need the name for type checking, or if it might cause a circular import), you can use

import typing

if typing.TYPE_CHECKING:
    from foo import Thing

TYPE_CHECKING is true only when a type checker is running (i.e. your code is not being evaluated for execution).

like image 69
AKX Avatar answered Sep 23 '22 08:09

AKX