Python — ошибка имени при использовании подсказки типа

#python

#python

Вопрос:

Я вижу Unresolved reference 'Segment' в pycharm, но в видео у нас с автором один и тот же код, и у автора, похоже, нет никаких ошибок.

Если я попытаюсь запустить его, я получу следующую ошибку:

 C:UsersUsernameanaconda3python.exe G:/Temp/Python/advanced-oop/flight.py
Traceback (most recent call last):
  File "G:/Temp/Python/advanced-oop/flight.py", line 4, in <module>
    class Flight:
  File "G:/Temp/Python/advanced-oop/flight.py", line 5, in Flight
    def __init__(self, segments: List[Segment]):
NameError: name 'Segment' is not defined

Process finished with exit code 1
  

Вот полный код:

 from typing import List


class Flight:
    def __init__(self, segments: List[Segment]):
        self.segments = segments

    @property
    def departure_point(self) -> str:
        return self.segments[0].departure


class Segment:
    def __init__(self, departure, destination):
        self.departure = departure
        self.destination = destination


flight = Flight([Segment('GLA', 'LHR')])
print(flight.departure_point)
  

Вот скриншот из видео, и он выполняется нормально.

введите описание изображения здесь

Комментарии:

1. Сегмент класса должен быть определен перед его использованием в аннотации типа. Переместите определение сегмента раньше.

2. Помещается Segment перед частью, на которую ссылается

3. Хорошо, так как же код автора работает нормально? Я думал о его перемещении

4. @John Вероятно, это тоже было определено где-то раньше. Или у автора есть некоторый python, который принимает любую аннотацию.

5. Откуда вы знаете, что это так? Возможно, то, что опубликовал автор, отличается от того, что на самом деле сработало для него / нее.

Ответ №1:

Когда строка def __init__(self, segments: List[Segment]): интерпретируется Python, класс Segment еще не определен. Поменяйте местами определения Flight и Segment , и код должен работать.

Ответ №2:

Класс Segment должен быть определен раньше, так как вы будете использовать его в Flight классе, в частности, в конструкторе.

 class Segment:
    def __init__(self, departure, destination):
        self.departure = departure
        self.destination = destination


class Flight:
    def __init__(self, segments: List[Segment]):
        self.segments = segments

@property
def departure_point(self) -> str:
    return self.segments[0].departure


flight = Flight([Segment('GLA', 'LHR')])
print(flight.departure_point)
  

Ответ №3:

Судя по скриншоту, которым вы поделились, Segment является неизвестным объектом, в основном python не знает, что подразумевается под Segment .

Для ее устранения,

  • Вырезать из строки # 20-23 и вставить ее выше class Flight

Комментарии:

1. Нет. Посмотрите любой из трех других ответов.

Ответ №4:

Переместите строки 20-23 выше ссылки в строке 12. Вы просто ссылаетесь на класс Segment до его определения.

По моему опыту, python компилируется последовательно (сверху вниз) большинством интерпретаторов. Это означает, что вы не можете ссылаться на переменную в строке 1, которая еще не объявлена, до строки N. В отличие, скажем, от Java, где вы можете размещать переменные где угодно, пока они находятся в области видимости.

Это имеет то преимущество, что код читается сверху вниз, но является немного более строгим с точки зрения порядка операций.

Комментарии:

1. before it is referenced вероятно, следует изменить на before it is defined .