Рубрики
Без рубрики

Решение проблемы «куриного яйца» с Python

. Tagged с Python, Python37, импорт, CirculardePendencies.

Привет!

Ничто не может быть более вкусным для питона, чем курица и яйца. Итак, сегодня наш Python решил решить старый философский вопрос: что было первым, курица или яйцо. Чтобы сделать это, он решил создать два класса, а затем выполнить некоторое моделирование, чтобы получить окончательный ответ на этот вопрос.

Хорошо, давайте начнем. Наш Python-это дранная PA всех питонов, а серийный номер-2,7. Для начала он создал 3 файла:

# filename: models/egg.py

import models.chicken


class Egg(object):
    def __init__(self, name):
        super(Egg, self).__init__()
        self.name = name

    def wait(self):
        return models.chicken.Chicken("Chicken from [{self.name}]".format(self=self))
# filename: models/chicken.py

import models.egg


class Chicken(object):
    def __init__(self, name):
        super(Chicken, self).__init__()
        self.name = name

    def create_egg(self):
        return models.egg.Egg("Egg of [{self.name}]".format(self=self))
# filename: main.py

import models.chicken


if __name__ == '__main__':
    # Decision maker!
    c = models.chicken.Chicken("Ryaba")
    print(c.create_egg().wait().create_egg().name)

Grand-Pa Python доволен результатами:

$ python2.7 main.py 
Egg of [Chicken from [Egg of [Ryaba]]]

Для тех из вас, кто скептически относится к круговой зависимости в Python – да, они поддерживаются, но только в некоторой степени. Как правило, когда интерпретатор видит Импорт модели.egg Он проверяет, импортируется ли этот модуль и, если он есть, использует адрес этого модуля из кэша. Если это не так, он сразу же создает запись в кэше, а затем начинает делать фактический импорт. Вот почему, если у вас есть только Import Заявления в вашем коде вы в безопасности.

Как только мы решим использовать от import Заявление, наши круговые зависимости не смогут быть разрешены. Давай попробуем!

# filename: models/egg.py

from models.chicken import Chicken


class Egg(object):
    def __init__(self, name):
        super(Egg, self).__init__()
        self.name = name

    def wait(self):
        return Chicken("Chicken from [{self.name}]".format(self=self))
# filename: models/chicken.py

from models.egg import Egg


class Chicken(object):
    def __init__(self, name):
        super(Chicken, self).__init__()
        self.name = name

    def create_egg(self):
        return Egg("Egg of [{self.name}]".format(self=self))
$ python2.7 main.py 
Traceback (most recent call last):
  File "main.py", line 1, in 
    import models.chicken
  File "/data/models/chicken.py", line 1, in 
    from models.egg import Egg
  File "/data/models/egg.py", line 1, in 
    from models.chicken import Chicken
ImportError: cannot import name Chicken

$ python3.7 main.py 
Traceback (most recent call last):
  File "main.py", line 1, in 
    import models.chicken
  File "/data/models/chicken.py", line 1, in 
    from models.egg import Egg
  File "/data/models/egg.py", line 1, in 
    from models.chicken import Chicken
ImportError: cannot import name 'Chicken' from 'models.chicken' (/data/models/chicken.py)

Это более или менее предсказуемо, и это настоящая проблема с курицей-яйцом. Чтобы импортировать Курица класс в яйцо Модуль вам нужно проанализировать курица Модуль (Итак, просто адрес модуля недостаточно), и для полного разбора курица Модуль, вам нужно завершить анализ яйцо модуль. Итак, ни за что.

ХОРОШО. И теперь мне нужно ваше полное внимание: мы собираемся заменить Импорт <пакет>. <Модуль> по Из Импорт <Модуль> Анкет

# filename: models/egg.py

from models import chicken


class Egg(object):
    def __init__(self, name):
        super(Egg, self).__init__()
        self.name = name

    def wait(self):
        return chicken.Chicken("Chicken from [{self.name}]".format(self=self))
# filename: models/chicken.py

from models import egg


class Chicken(object):
    def __init__(self, name):
        super(Chicken, self).__init__()
        self.name = name

    def create_egg(self):
        return egg.Egg("Egg of [{self.name}]".format(self=self))

И результат немного неожиданно:

$ python2.7 main.py 
Traceback (most recent call last):
  File "main.py", line 1, in 
    import models.chicken
  File "/data/models/chicken.py", line 1, in 
    from models import egg
  File "/data/models/egg.py", line 1, in 
    from models import chicken
ImportError: cannot import name chicken

$ python3.7 main.py 
Egg of [Chicken from [Egg of [Ryaba]]]

Таким образом, Python3 изменил способ импорта пакетов, как правило, они добавляются к Sys.Modules раньше, чем Python2. Хорошо знать.

И последний сюрприз на сегодня. Теперь мы используем Импорт . как <псевдоним> синтаксис.

# filename: models/egg.py

import models.chicken as chicken


class Egg(object):
    def __init__(self, name):
        super(Egg, self).__init__()
        self.name = name

    def wait(self):
        return chicken.Chicken("Chicken from [{self.name}]".format(self=self))
# filename: models/chicken.py

import models.egg as egg


class Chicken(object):
    def __init__(self, name):
        super(Chicken, self).__init__()
        self.name = name

    def create_egg(self):
        return egg.Egg("Egg of [{self.name}]".format(self=self))

И можете ли вы предсказать выход?

$ python2.7 main.py 
Traceback (most recent call last):
  File "main.py", line 1, in 
    import models.chicken
  File "/data/models/chicken.py", line 1, in 
    import models.egg as egg
  File "/data/models/egg.py", line 1, in 
    import models.chicken as chicken
AttributeError: 'module' object has no attribute 'chicken'

$ python3.6 main.py 
Traceback (most recent call last):
  File "main.py", line 1, in 
    import models.chicken
  File "/data/models/chicken.py", line 1, in 
    import models.egg as egg
  File "/data/models/egg.py", line 1, in 
    import models.chicken as chicken
AttributeError: module 'models' has no attribute 'chicken'

$ python3.7 main.py 
Egg of [Chicken from [Egg of [Ryaba]]]

Python3.7 Won:) ОК. Здесь действительно произошло то, что был ошибка в Импорт A.B.C As D Синтаксис, который был Исправлено В версии 3.7.

Спасибо за чтение!

Оригинал: “https://dev.to/xni/solving-the-chicken-egg-problem-with-python-4ocn”