LINUX.ORG.RU

Можно ли from * import * заставить игнорировать __main__ контекст?

 ,


0

1

tests/init.py:

from tests.lib1 import Lib1
from tests.lib2 import Lib2

tests/lib1.py:

print("lib1")

class Lib1:
    pass

tests/lib2.py:

print("lib2")

class Lib2:
    pass

main.py:

from tests import Lib2

result:

lib1
lib2

Можно ли заставить from tests.lib2 игнорировать main контекст, а только дергать нужную либу? Без костылей, которые intelisense ломают.

★★★★★

Последнее исправление: steemandlinux (всего исправлений: 6)

Ответ на: комментарий от Virtuos86

Есть каталог tests, типа наша либа. В ней лежат файлы lib1.py и lib2.py, в них классы Lib1 и Lib2, есть общий реэкспорт init.py, который импортирует Lib1 и Lib2. Проблема в том, что когда в питоне импортируешь файл (init.py), даже через from, он исполняет весь контекст импортируемого файла (init.py).

Можно как-нибудь заставить питон не исполнять контекст init.py, а только исполнить строчку реэкспорта?

steemandlinux ★★★★★
() автор топика
Ответ на: комментарий от steemandlinux

Есть каталог tests, типа наша либа.

Это называется «пакет» в Python. Хотя нет, тогда __init__.py должен быть.

А что такое main.py?

Virtuos86 ★★★★★
()
Последнее исправление: Virtuos86 (всего исправлений: 1)
Ответ на: комментарий от Flotsky

Автор хочет наоборот - чтобы при main не было допдействий.

mxfm ★★
()
Ответ на: комментарий от Flotsky

Неа, это совсем не то, от циркулярной пилы не спасёт.

steemandlinux ★★★★★
() автор топика
Ответ на: комментарий от mxfm

Я не понимаю, почему питон исполняет либу даже при использовании from? Они предлагают не пользоваться реэкспортом, а дергать напрямую все классы? Я кстати заметил что очень часто в популярных библиотеках init не заполнен. Можно типа сделать отдельный каталог с экспортными модулями, но это пипец как грязно выглядит.

steemandlinux ★★★★★
() автор топика
Последнее исправление: steemandlinux (всего исправлений: 2)
Ответ на: комментарий от steemandlinux

Я не понимаю, почему питон исполняет либу даже при использовании from?

ЕМНИП, при импорте import module выполняется что-то вроде globals()["module"] = {}; execfile("module.py", globals(), module), не соврать бы — давно питон не ковырял. Форма from-import не избавляет от той части, что execfile...

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86
inspect.stack()
code_context=['from tests import Lib2\n']

Не работает :( Если в этом же контексте вызвать второй from, то повторного вызова не происходит.

steemandlinux ★★★★★
() автор топика
Последнее исправление: steemandlinux (всего исправлений: 3)
Ответ на: комментарий от Virtuos86

Я не нашел способа полного игнорирования main :(

Я вот не понимаю, допустим мне нужен import для типизации, но всё равно надо исполнять основной контекст. В итоге при каждом чихе ловлю циркулярку. Осталось проверить как среагирует intellisense на это.

Не работает :(

steemandlinux ★★★★★
() автор топика
Последнее исправление: steemandlinux (всего исправлений: 5)
Ответ на: комментарий от steemandlinux

но всё равно надо исполнять основной контекст

Да просто у тебя модуль написан "кривовато". Все что не должно выполняться при импорте прикрывается костылем "if __name__ == __main__". Вообще в целом то что в модуле что-то там само запускается без явного указания это не правильно.

Смотри с другой стороны - вот у тебя есть какой-то черный ящик "модуль", как ты можешь работать с каким-то его куском при этом не загрузив его полностью? Считай что вот это "from A import B" это тупо про пространство имен.

$ cat mymodule.py 
#!/usr/bin/env python3

print('loading "mymodule"')

def foo():
    print('foo')

def bar():
    print('bar')

def baz():
    print('baz')

>>> from mymodule import foo
loading "mymodule"
>>> from mymodule import bar
>>> import sys
>>> sys.modules['mymodule'].baz()
baz
>>> 

Как сделать то что ты хочешь - как сказали выше, без правки модуля - никак. Ну разве что можно попытаться как-то сам файл прочитать именно как "текст" и потом пробовать это "eval'ить".

micronekodesu ★★★
()
Ответ на: комментарий от micronekodesu

У меня вообще нет кода во внешнем контексте кроме импортов и подключения внешнего логгера (никаких отсылок к библиотеке нет с него), видимо я что-то перемудрил с зависимостями. Либо просто импортировать напрямую, не трогать структуру и в случае изменений приколотить костыли, чтобы не отвалилось.

steemandlinux ★★★★★
() автор топика
Последнее исправление: steemandlinux (всего исправлений: 2)
Ответ на: комментарий от steemandlinux

Решений как мин два:

  1. убрать импорт всего из инита
  2. убрать лишний код из модулей оставив там только обьявление классов и функций, тогда лишний импорт перестает быть проблемой.

Обычно используют вариант 2

AntonI ★★★★
()
Ответ на: комментарий от AntonI

Есть еще третий, pyi, только по python stubs нет адекватной документации :(

Вот как авторы pylance объяснили плагину где брать описание print?

steemandlinux ★★★★★
() автор топика
Последнее исправление: steemandlinux (всего исправлений: 1)
Ответ на: комментарий от steemandlinux

Никогда ними не работал, но кмк это вообще к обсуждаемому вопросу не относится.

AntonI ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.