ошибка python в import [duplicate]

Для динамического поворота используйте GROUP_CONCAT с CONCAT. Функция GROUP_CONCAT объединяет строки из одной группы в одну строку с различными опциями.

SET @sql = NULL;
SELECT
    GROUP_CONCAT(DISTINCT
    CONCAT(
      'SUM(CASE WHEN action = "',
      action,'"  AND ', 
           (CASE WHEN pagecount IS NOT NULL 
           THEN CONCAT("pagecount = ",pagecount) 
           ELSE pagecount IS NULL END),
      ' THEN 1 ELSE 0 end) AS ',
      action, IFNULL(pagecount,'')

    )
  )
INTO @sql
FROM
  t;

SET @sql = CONCAT('SELECT company_name, ', @sql, ' 
                  FROM t 
                   GROUP BY company_name');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

DEMO HERE

614
задан Mark Harrison 14 April 2015 в 07:56
поделиться

19 ответов

Вы можете перезагрузить модуль, когда он уже был импортирован, используя встроенную функцию reload в Python 2:

import foo

while True:
    # Do some things.
    if is_changed(foo):
        foo = reload(foo)

В Python 3, reload был перемещен в модуль imp . В 3.4 imp устарели в пользу importlib , а к последнему добавили reload . При таргетинге 3 или более поздней версии либо ссылайтесь на соответствующий модуль при вызове reload или импортируйте его.

Я думаю, что это то, что вы хотите. Веб-серверы, такие как сервер разработки Django, используют это, чтобы вы могли видеть эффекты изменений кода без перезапуска самого процесса сервера.

Чтобы процитировать из документов:

Python код модулей перекомпилирован, а код модуля-уровня повторно выполняется, определяя новый набор объектов, которые привязаны к именам в словаре модуля. Функция init модулей расширения не вызывается второй раз. Как и все другие объекты в Python, старые объекты восстанавливаются только после того, как их отсчеты ссылок упадут до нуля. Имена в пространстве имен модулей обновляются, чтобы указывать на любые новые или измененные объекты. Другие ссылки на старые объекты (например, имена, внешние по отношению к модулю) не отскакивают, чтобы ссылаться на новые объекты и должны обновляться в каждом пространстве имен, где они встречаются, если это необходимо.

Как вы отметили в своем вопросе, вам придется восстановить объекты Foo, если класс Foo находится в модуле foo.

558
ответ дан endolith 21 August 2018 в 00:09
поделиться
  • 1
    на самом деле, сервер django dev перезагружается, когда вы меняете файл .. (он перезапускает сервер, а не просто перезагружает модуль) – hasen 13 January 2009 в 07:36
  • 2
    где это "is_changed" функция, исходящая из? я не вижу на нем документации и не запускается в моей среде Python 3.1.3 и не работает в версии 2.6.4. – jedmao 17 June 2011 в 15:29
  • 3
  • 4
    Не будет работать в случае from m import X. – BartoszKP 3 June 2014 в 21:26
  • 5
    @BartoszKP, если X не является модулем, вы можете import sys; reload(sys.modules[X.__module__]) – drevicko 16 April 2016 в 15:31

Для Python 2 используйте встроенную функцию reload () :

reload(module)

Для Python 2 и 3.2-3.3 используйте перезагрузку из модуля imp :

import imp
imp.reload(module)

Но imp устарел с версии 3.4 в пользу importlib , поэтому используйте:

import importlib
importlib.reload(module)

или

from importlib import reload
reload(module)
35
ответ дан Brian Burns 21 August 2018 в 00:09
поделиться
  • 1
    для обработки любого из этих случаев: from six import reload_module (сначала нужно pip install six) – Anentropic 30 October 2017 в 17:46
  • 2
    @Anentropic: Хороший совет рекомендовать использовать шесть пакетов, но синтаксис from six.moves import reload_module ( doc ) – x0s 4 January 2018 в 21:32

В Python 3.0-3.3 вы должны использовать: imp.reload(module)

BDFL имеет ответил на этот вопрос.

Однако imp устарел в 3.4, в пользу importlib (спасибо @Stefan! ).

I думаю, , поэтому вы теперь будете использовать importlib.reload(module) , хотя я не уверен.

233
ответ дан Community 21 August 2018 в 00:09
поделиться
if 'myModule' in sys.modules:  
    del sys.modules["myModule"]
53
ответ дан Daniel 21 August 2018 в 00:09
поделиться
  • 1
  • 2
    Если ваш модуль импортирует собственные подмодули, вам может понадобиться их удалить. Что-то вроде [del(sys.modules[mod] for mod in sys.modules.keys() if mod.startswith('myModule.')]. – drevicko 24 June 2014 в 10:00

Enthought Traits имеет модуль, который работает достаточно хорошо для этого. https://traits.readthedocs.org/en/4.3.0/_modules/traits/util/refresh.html

Он перезагрузит любой измененный модуль и обновлять другие модули и объекты, которые его используют. Он не работает большую часть времени с методами __very_private__ и может захлебываться от наследования классов, но это избавляет меня от сумасшедшего времени от необходимости перезапуска приложения-хозяина при написании PyQt guis или материала, который запускается внутри таких программ, как Maya или Nuke. Это не работает, возможно, в 20-30% случаев, но это все еще невероятно полезно.

Пакет Enthoughtht не перезагружает файлы в тот момент, когда они меняются - вы должны называть это явно - но это не должно " t быть все, что трудно реализовать, если вам это действительно нужно

5
ответ дан flipthefrog 21 August 2018 в 00:09
поделиться

Другим способом может быть импорт модуля в функцию. Таким образом, когда функция завершается, модуль получает собранный мусор.

-1
ответ дан hackbot89 21 August 2018 в 00:09
поделиться
  • 1
    Модуль никогда не получит сбор мусора, потому что глобальная ссылка сохраняется, по крайней мере, в sys.modules. – cpburnz 21 October 2016 в 17:02

Может быть особенно сложно удалить модуль, если он не является чистым Python.

Вот некоторая информация из: Как я могу удалить импортированный модуль?

Вы можете использовать sys.getrefcount (), чтобы узнать фактическое количество ссылок.

>>> import sys, empty, os
>>> sys.getrefcount(sys)
9
>>> sys.getrefcount(os)
6
>>> sys.getrefcount(empty)
3

Число больше 3 указывает, что оно будет будет трудно избавиться от модуля. Домашний «пустой» (не содержащий ничего) модуль должен быть мусором, собранным после

>>> del sys.modules["empty"]
>>> del empty

, поскольку третья ссылка является артефактом функции getrefcount ().

75
ответ дан Honest Abe 21 August 2018 в 00:09
поделиться
  • 1
    Я только что обнаружил, что если модуль является частью пакета, вы также должны удалить его: setattr(package, "empty", None) – u0b34a0f6ae 11 May 2010 в 13:33
  • 2
    Это правильное решение, особенно если у вас есть пакет с вложенными модулями. reload() только перезагружает самый верхний модуль, и все, что внутри него, не будет перезагружено, если вы не удалите его сначала из sys.modules. – Cerin 5 December 2016 в 21:05

Другой вариант. Посмотрите, что Python по умолчанию importlib.reload просто переименует библиотеку, переданную в качестве аргумента. Он не перезагрузит библиотеки, которые импортируют ваш lib. Если вы изменили много файлов и имеете несколько сложный пакет для импорта, вы должны сделать глубокую перезагрузку.

Если вы установили IPython или Jupyter , вы можете использовать функцию для глубокой перезагрузки всех libs:

from IPython.lib.deepreload import reload as dreload
dreload(foo)

Если у вас нет Jupyter, установите его с помощью этой команды в свою оболочку:

pip3 install jupyter
1
ответ дан IanS 21 August 2018 в 00:09
поделиться
  • 1
    И этот Ipython dreload и reload () из importlib жалуется на reload() argument must be module. Я использую импорт специальных функций и, похоже, не работает. Использование встроенных модулей работает. :-( Это пустая трата времени на перезагрузку iPython за каждое небольшое изменение, внесенное мной в мой код ... – erm3nda 11 August 2018 в 13:58

2018-02-01

  1. модуль foo должен быть успешно импортирован заранее.
  2. from importlib import reload, reload(foo)

31.5. importlib - Реализация импорта - Документация Python 3.6.4

2
ответ дан JawSaw 21 August 2018 в 00:09
поделиться

reload(module), но только если он полностью автономный. Если что-либо еще имеет ссылку на модуль (или любой объект, принадлежащий модулю), тогда вы получите тонкие и любопытные ошибки, вызванные тем, что старый код висит дольше, чем вы ожидали, и такие вещи, как isinstance, не работают с разными версии одного и того же кода.

Если у вас есть односторонние зависимости, вы также должны перезагрузить все модули, зависящие от перезагруженного модуля, чтобы избавиться от всех ссылок на старый код. И затем перезагружайте модули, которые зависят от перезагруженных модулей, рекурсивно.

Если у вас есть циклические зависимости, которые очень распространены, например, когда вы имеете дело с перезагрузкой пакета, вы должны выгрузить все модули в группе за один присест. Вы не можете сделать это с помощью reload(), поскольку он будет повторно импортировать каждый модуль до того, как его зависимости будут обновлены, что позволит использовать старые ссылки для ползучести в новые модули.

Единственный способ сделать это в этом случае это взломать sys.modules, что является неподдерживаемым. Вам нужно будет пройти и удалить каждую запись sys.modules, которую вы хотели бы перезагрузить при следующем импорте, а также удалить записи, значения которых None для решения проблемы с реализацией, связанной с кэшированием, при неудачном относительном импорте. Это не очень приятно, но пока у вас есть полностью автономный набор зависимостей, который не оставляет ссылки за пределами его кодовой базы, он работоспособен.

Вероятно, лучше всего перезапустить сервер. : -)

57
ответ дан jdloft 21 August 2018 в 00:09
поделиться
  • 1
    Разве это не так важно для этого сценария? – Josh 31 May 2012 в 22:10
  • 2
    @Josh: нет, это для перезагрузки дерева пакетов, и даже тогда он работает только до тех пор, пока у пакета нет внешних / круговых зависимостей. – bobince 2 June 2012 в 11:29
  • 3
    Вы можете детализировать часть с None значениями, потому что я точно выполняю эту проблему: я удаляю элементы из sys.modules, а после повторного импорта некоторые импортированные зависимости - None. – schlamar 26 March 2013 в 12:15
  • 4
    @shclamar: см. stackoverflow.com/questions/1958417/… (и ссылки оттуда) для фона. Мне непонятно (даже смотря на код import.c), как элементам None удалось вернуться через механизм импорта, когда «реальные» записи были удалены, и я не могу показаться, что это произошло 2,7; в будущем, безусловно, это уже не проблема, поскольку скрытый относительный импорт ушел. Тем временем удаление всех записей с None значением, похоже, исправить. – bobince 26 March 2013 в 17:13
  • 5

Принятый ответ не обрабатывает случай X импорта Y. Этот код обрабатывает и стандартный случай импорта:

def importOrReload(module_name, *names):
    import sys

    if module_name in sys.modules:
        reload(sys.modules[module_name])
    else:
        __import__(module_name, fromlist=names)

    for name in names:
        globals()[name] = getattr(sys.modules[module_name], name)

# use instead of: from dfly_parser import parseMessages
importOrReload("dfly_parser", "parseMessages")

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

14
ответ дан Joseph Garvin 21 August 2018 в 00:09
поделиться
  • 1
    Заметив проблему, globals () относится к модулю, в котором вы определяете эту функцию, поэтому, если вы определяете ее в модуле, отличном от того, который вы вызываете в нем, это не работает. – Joseph Garvin 11 October 2014 в 21:29
  • 2
    Для интерактивных, после >>> from X import Y для перезагрузки do >>> __import__('X', fromlist='Y') – Bob Stein 29 January 2015 в 18:43
  • 3
    @ BobStein-VisiBone, есть ли способ сделать эту работу, когда fromlist='*'? – Mike C 28 July 2015 в 19:55
  • 4
    Хороший вопрос, не знаю @MikeC. Кстати, я склонен прекратить почти все использование from в операциях импорта. Просто stark import <package> и явный package.symbol в коде. Понимать это не всегда возможно или желательно. (Вот одно исключение: из будущего импорта print_function.) – Bob Stein 29 July 2015 в 00:21
  • 5
    Майк С: что для меня работает foo = reload(foo); from foo import * – rampion 19 October 2016 в 13:09

Следующий код позволяет вам совместимость с Python 2/3:

try:
    reload
except NameError:
    # Python 3
    from imp import reload

Вы можете использовать его как reload() в обеих версиях, что упрощает работу.

20
ответ дан Matt Clarkson 21 August 2018 в 00:09
поделиться

для меня в случае с Abaqus, так оно и работает. Представьте, что ваш файл - Class_VerticesEdges.py

sys.path.append('D:\...\My Pythons')
if 'Class_VerticesEdges' in sys.modules:  
    del sys.modules['Class_VerticesEdges']
    print 'old module Class_VerticesEdges deleted'
from Class_VerticesEdges import *
reload(sys.modules['Class_VerticesEdges'])
1
ответ дан Matt S 21 August 2018 в 00:09
поделиться

Операция unload может быть легко выполнена следующим образом:

import pythonlib
del pythonlib

у вас больше ничего не будет связано с этой библиотекой.

0
ответ дан Mincă Daniel Andrei 21 August 2018 в 00:09
поделиться

Если вы являетесь not на сервере, но разрабатываете и должны часто перезагружать модуль, вот хороший отзыв.

Сначала сделайте убедитесь, что вы используете превосходную оболочку IPython из проекта Jupyter Notebook. После установки Jupyter вы можете запустить его с помощью ipython или jupyter console или даже лучше jupyter qtconsole, что даст вам красивую раскрашенную консоль с завершением кода в любой ОС.

Теперь в ваша оболочка, введите:

%load_ext autoreload
%autoreload 2

Теперь, каждый раз, когда вы запускаете свой скрипт, ваши модули будут перезагружены.

Помимо 2, существуют другие опции магии автозагрузки :

%autoreload
Reload all modules (except those excluded by %aimport) automatically now.

%autoreload 0
Disable automatic reloading.

%autoreload 1
Reload all modules imported with %aimport every time before executing the Python code typed.

%autoreload 2
Reload all modules (except those excluded by %aimport) every time before
executing the Python code typed.
6
ответ дан neves 21 August 2018 в 00:09
поделиться
  • 1
    Совершенно, я полностью забыл о магических навыках Ipython :-) – erm3nda 11 August 2018 в 14:02

Для таких, как я, которые хотят выгрузить все модули (при запуске в интерпретаторе Python под Emacs ):

   for mod in sys.modules.values():
      reload(mod)

Дополнительная информация находится в Перезагрузка модулей Python .

6
ответ дан Peter Mortensen 21 August 2018 в 00:09
поделиться
  • 1
    На самом деле это не работает надежно (в версии 2.6), потому что не все в sys.modules.values() является модулем. Например: & gt; & gt; & gt; & gt; & gt; type (sys.modules.values ​​() [1]) & lt; class 'email.LazyImporter' & gt; Поэтому, если я пытаюсь запустить этот код, он падает (я знаю, что это не значит, что это практическое решение, просто указывая на это). – Francis Davey 18 June 2010 в 09:04
  • 2
    Это даже не работает на ранних питонах - как написано. Я должен был исключить некоторые имена. Я обновлю сообщение, когда переведу этот код на свой новый компьютер. – Arkadiy 19 June 2010 в 06:32
  • 3
    Работает отлично в Python 2.7 после некоторых изменений: if mod and mod.__name__ != "__main__": imp.reload(mod) – Czarek Tomczak 15 September 2012 в 15:24
  • 4
    Это хорошо работает для меня: import imp [reload (m) для m в sys.modules.values ​​(), если m и not "" в m .__ name , а не imp.is_builtin (m .__ name__)] – Patrick Wolf 17 June 2015 в 23:40
  • 5
    @Patrick - отредактируйте ответ так, как вы считаете нужным ... – Arkadiy 18 June 2015 в 12:16

Те, кто использует python 3 и перезагружаются из importlib.

Если у вас возникли проблемы, похоже, что модуль не перезагружается ... Это потому, что ему нужно некоторое время для перекомпиляции pyc (до 60 секунд). Я пишу этот намек только для того, чтобы вы знали, что вы столкнулись с такой проблемой.

2
ответ дан PythonMan 21 August 2018 в 00:09
поделиться

Это современный способ перезагрузки модуля:

from importlib import reload

Просто введите reload(MODULE_NAME), заменив MODULE_NAME на имя модуля, который вы хотите перезагрузить.

Например, reload(math) перезагружает математическую функцию.

6
ответ дан Richie Bendall 21 August 2018 в 00:09
поделиться
  • 1
    Или просто from importlib import reload. Затем вы можете сделать reload(MODULE_NAME). Эта функция не нужна. – pault 2 February 2018 в 19:39
  • 2
    Я считаю, что modulereload(MODULE_NAME) более понятен, чем просто reload(MODULE_NAME) и имеет более низкий шанс конфликта с другими функциями. – Richie Bendall 17 July 2018 в 22:30
  • 3
    @RichieBendall Извините, но этот ответ совершенно неверен. Функция reload () принимает объект модуля, а не имя модуля ... Прочитайте документы: docs.python.org/3/library/importlib.html#importlib.reload И я согласен с @ pault - это "как модульная загрузка" является сверхъестественным. – mbdevpl 1 August 2018 в 01:09
  • 4
    – Richie Bendall 4 August 2018 в 04:34

У меня много проблем с попыткой перезагрузить что-то внутри Sublime Text, но, наконец, я смог написать эту утилиту для перезагрузки модулей в Sublime Text на основе кода sublime_plugin.py, используемого для перезагрузки модулей.

ниже, вы можете перезагрузить модули из путей с пробелами в своих именах, а затем после перезагрузки вы можете просто импортировать, как обычно.

def reload_module(full_module_name):
    """
        Assuming the folder `full_module_name` is a folder inside some
        folder on the python sys.path, for example, sys.path as `C:/`, and
        you are inside the folder `C:/Path With Spaces` on the file 
        `C:/Path With Spaces/main.py` and want to re-import some files on
        the folder `C:/Path With Spaces/tests`

        @param full_module_name   the relative full path to the module file
                                  you want to reload from a folder on the
                                  python `sys.path`
    """
    import imp
    import sys
    import importlib

    if full_module_name in sys.modules:
        module_object = sys.modules[full_module_name]
        module_object = imp.reload( module_object )

    else:
        importlib.import_module( full_module_name )

def run_tests():
    print( "\n\n" )
    reload_module( "Path With Spaces.tests.semantic_linefeed_unit_tests" )
    reload_module( "Path With Spaces.tests.semantic_linefeed_manual_tests" )

    from .tests import semantic_linefeed_unit_tests
    from .tests import semantic_linefeed_manual_tests

    semantic_linefeed_unit_tests.run_unit_tests()
    semantic_linefeed_manual_tests.run_manual_tests()

if __name__ == "__main__":
    run_tests()

Если вы запускаете в первый раз, это должно загрузить модуль , но если позже вы снова сможете использовать метод / функцию run_tests(), он перезагрузит файлы тестов. С Sublime Text (Python 3.3.6) это происходит очень часто, потому что его интерпретатор никогда не закрывается (если вы не перезапустите Sublime Text, т. Е. Интерпретатор Python3.3).

0
ответ дан user 21 August 2018 в 00:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: