python. перекрёстный импорт.
Не питонист, но первое, что приходит в голову — импортить внутри функции, которой надо то, что импортится.
Что я делаю не так?Перекрестно импортируешь.
Если очень хочется, то можно делать так:
def calc_profit:
from m1 import calc_income
return calc_income/2
Почему не работает так, как я написал? Зачем так сделали?
UPD: примерно разобрался, как работает. Хотя вроде это не очень очевидное поведение.
Зачем так сделали?Ибо делать чтоб это работало - весьма геморройно.
Собственно я даже не особо понимаю как это можно сделать.
В сях, например, это решается #ifdef'ами в заголовках или #pramga once,
но там заголовочные файлы не интерпретируются. При этом думаю можно
придумать конструкцию которая и там работать не будет.
print "INIT m1"
def calc_income:
return 2
from m2 import some_surname
def get_username:
return 'Alex' + some_surname
print "INIT m1"
def some_surname:
return 'Black'
from m1 import calc_income
def calc_profit:
return calc_income/2
Т.е. проблема ровно в том, что в тот момент, когда m2 запрашивается функцию из m1, m1 не доинициализировался до нужной функции
У меня просто было ошибочное представление, что модуль - это не скрипт, который исполняется построчно, а некоторое неупорядочное множество разных сущностей (объявление функций, переменных и т.д.)
У меня просто было ошибочное представление, что модуль - это не скрипт, который исполняется построчно, а некоторое неупорядочное множество разных сущностей (объявление функций, переменных и т.д.)И как ты себе представляешь реализацию этого? Питон - интерпретируемый язык, поэтому
пока ты не добрался до объявления нужных вещей, их у тебя просто не существует.
Вообще самый разумный совет был с импортом внутри функции
пока вызов не сделали, оставить заглушку. А когда попросят вызвать и, если не повезло, падать в NameError.
ну не лезть туда. пока не требуют.модуль может не только что-то свое выдавать, но и модифицировать чужое или что-нибудь полезное делать
например, при загрузке рассчитывать какие-нибудь статические значения, словари там или еще что
или monkey patching, который люто рулит
да и синтаксис неплохо было бы проверить
так что не выйдет ничего не делать при импорте
в той же жабе это как-то работает. в чем глобальное отличие жабы от питона, из-за которого так сделать нельзя?
в чем глобальное отличие жабы от питона, из-за которого так сделать нельзя?ну насколько я понимаю, проблема в том что выражение
from module import obj
не может быть нормально обработано, пока мы не прочитали _весь_ module и все его вложенности
в яве всё таки более статические типы/имена переменных - если уж что-то объявили то не можем через
несколько строчек передумать, забыть про это и переобъявить заново
upd
Глобальное отличие, конечно же, в том что ява - компилируемый язык
не может быть нормально обработано,
в моём примере обработалось. Это баг? ведь потом могло быть переопределение функции.
Если так размышлять, можно сказать, что нельзя ничего импортировать, т.к. в будущем кто-то что-то может изменить.
в моём примере обработалось. Это баг? ведь потом могло быть переопределение функции.Может быть переопределно. А может и не быть.
Это не баг, это побочные эффекты механизма загрузки модулей.
Поскольку 'import module' сначала лезет в список уже загруженных и оттуда пытается взять,
в момент вызова второго импорта в первом уже прописаны нужные значения.
Собственно проблема в изрядной степени надуманная, циклические зависимости вообще зло, независимо от языка.
в той же жабе это как-то работает. в чем глобальное отличие жабы от питона, из-за которого так сделать нельзя?отличие в том, что питон - интерпретеруемый. В яве ты объявляешь класс. В питоне ты при инициализации ты создаёшь классы. И всё остальное тоже: функции, константы - являются объектами, создаваемыми внутри очень большой инициализурующей модуль процедуры при её запуске, происходящем при загрузке модуля.
Настолько же, насколько и ява (ну кроме может того момента, что нет более-менее распространенного интерпретатора, понимающего сразу исходный код - распространенные понимают обычно байткод.
И в питоне и в яве есть байткод, и там и там есть jit. в чем разница-то?
>В яве ты объявляешь класс. В питоне ты при инициализации ты создаёшь классы.
В яве можно в рантайме поменять существующий класс.
Более того, при компиляции в байткод у тебя может быть одна версия класса, а во время интерпретации - другая, и ты легко словишь в рантайме Error из-за отсутствия метода в классе.
И в питоне и в яве есть байткод, и там и там есть jit. в чем разница-то?Хде есть jit?
Ну и вообще терзают меня смутные мысли, что товарищ Гвидо придерживается точки зрения, что некоторые сомнительные фичи не стоят усложнения интерпретатора. И учитывая почти полное отсутствие рантайм оптимизаций в мейнстрим интерпретаторах, это точка зрения может иметь еще и довод по производительности.
И "import SomeNameSpace" реально что-то делает, в отличии от "using SomeNameSpace" (или как там в джаве)
Грубо говоря. Если в модуле тело функции выкачивается из инета, то "import SomeNameSpace" может сломаться, когда инет не работает, а может и нормально отработать.
в питоне и яве.
даже после компиляции в байткод?
>Грубо говоря. Если в модуле тело функции выкачивается из инета, то "import SomeNameSpace" может сломаться, когда инет не работает, а может и нормально отработать.
вообще говоря, тело класса в яве тоже может выкачиваться из инета, только этим почти никто не пользуется. так в чем глобальная разница-то?
даже после компиляции в байткод?Если я ничего не путаю, питоновский байткод всего лишь более машинночитаемый вид исходников.
При его загрузке происходит всё то же самое, кроме синтаксического разбора.
По крайней мере из него прекрасно восстанавливается обычный код (не всегда, правда, если всякие корявые случаи)
Как правильно уже здесь отметили в питоне практически нет компиляции, так что каждая загрузка требует обработки и рюхания кода.
Вот например типичный кусок:
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
Это запросто может быть в модуле в корне, так что при его загрузке мы получим разные результаты в зависимости от окружения.
да я уже побаловался с этим вашим питоном и понял, что у вас беда с ссылками на функции (даже вспомнил, что слышал об этом раньше поэтому видимо и импорт такой кривой.
import m1
... m1.whatever ...
Доступ к атрибутам модуля будем происходить именно там, где они нужны.
PyPy за счёт jitа догнало и обогнало на некоторых тестах CPythonИ в питоне и в яве есть байткод, и там и там есть jit. в чем разница-то?Хде есть jit?
PyPy за счёт jitа догнало и обогнало на некоторых тестах CPythonЭто несерьезно. Обсуждать джит компилятор не продакшн системы.
Теоретически можно написать все что угодно, вопрос в сроках-целесообразности. Но до сих пор в питоне джит компилятора, которым можно пользоваться, нет.
Оставить комментарий
Phoenix
main.pym2.py
m2.py
исполняем:
что делать-то?
На практике было так. в одном файле лежит список констатнт.
в некотором файле utils.py есть функция, которая проверяет, является ли значение поля допустимым (кроме всего прочего делает from ... import.... из файла со списком констант)
ну и сам файл где лежит список констант в одной функции использует вспомогательную улилиту из utils.py
Что я делаю не так?