Тест для устанавливаемых зависимостей от модуля Python

Вот пример рекурсивного решения, основанного на foreach, для вашего кода, работающего с предоставленным вами набором данных.

    $sourceArray = array("a" => 3, "b" => 0, "c" => array("1" => "aa", "2" => 1, "3" => array("a1" => 6, "a2" => 5781, "a3" => array("1" => 0, "2" => 19550, "3" => 5781)), array( "a1" => 1, "a2" => 5781, "a3" =>array("1" => 0, "2" => 19550, "3" => 5781 ))), array( "1" => "aa", "2" => 1, "3" => array( array( "a1" => 6, "a2" => 5781, "a3" => array( "1" => 0, "2" => 19550,"3" => 5781))), array( "a1" => 1, "a2" => 5781, "a3" =>array(  "1" => 0, "2" => 19550, "3" => 5781))));

    print_r($sourceArray,1);

    function removeKeys($keys, $sourceData) {

        foreach ($sourceData as $key=>$val) {

            if (in_array($key, $keys, true)) {
                unset($sourceData[$key]);
            } else if (is_array($val)) {
                $sourceData[$key] = removeKeys($keys, $sourceData[$key]);
            }
        }
        return $sourceData;
    }

    $keysToRemove = array("b","2","a2");

    $newArray = removeKeys($keysToRemove, $sourceArray);

    print_r($newArray);

Простота реализации, хотя получение ваших данных было сложной задачей. В этом примере я заметил «ошибку» в том, что если ключ равен «0» в исходном массиве, он все равно удаляется, даже если его нет в массиве $ keys.

Но я предполагаю, что этого примера достаточно, чтобы ответить на ваш вопрос, и что мой заявленный крайний случай не произойдет (т. Е. «0» не является ключевым значением в вашем массиве.) Если вы используете « 0 "в качестве ключа вы можете добавить дополнительную логику, чтобы перехватить этот случай, но это немного замедлит работу функции, поэтому я оставлю этот выбор на ваше усмотрение.

(Обратите внимание, что ошибка, упомянутая выше, исправлена ​​сейчас и в коде ... см. Примечания ниже для решения от оригинального постера)

7
задан Brian M. Hunt 20 April 2009 в 14:27
поделиться

4 ответа

Вы можете использовать функцию __ import __ () , как это ::

for module in modules:
    try:
        __import__(module)
    except ImportError:
        do_something()

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

import imp
for module in modules:
    try:
        imp.find_module(module)
    except ImportError:
        do_something()

Да, и причину, по которой вы не можете использовать eval () потому что import является оператором, а не выражением. Вы можете использовать exec , если вы действительно хотите, хотя я бы не рекомендовал это ::

for module in modules:
    try:
        exec 'import ' + module
    except ImportError:
        do_something()
8
ответ дан 6 December 2019 в 08:45
поделиться

Что с этим не так?

modules = set(["sys", "os", "jinja"])
for m in modules:
    try:
        __import__(m)
    except ImportError:
        # do something

Выше используется функция __ import __ . Кроме того, он строго проверяет, существует ли он или нет - он фактически не сохраняет импорт, но вы можете легко изменить его, чтобы сделать это.

6
ответ дан 6 December 2019 в 08:45
поделиться
modules = set(["sys", "os", "jinja"])
try:
  for module in modules:
    __import__(module)
  doSomething()
except ImportError, e:
    print e
2
ответ дан 6 December 2019 в 08:45
поделиться

Стоит понять компромиссы между подходом find_module и подходом __ import __ :

  • __ import __ ('foo') вызовет любые побочные эффекты загрузки файла module, независимо от того, сохраняете ли вы ссылку на импортированный модуль. Это может быть нормально или нет.
  • find_module ('foo') не вызовет никаких побочных эффектов, поэтому всегда должен быть безопасным.
  • ни один из подходов не работает хорошо, если модуль найден, но есть другие проблемы во время загрузки (например,SyntaxError, NameError, ...)
  • В зависимости от того, как вы обрабатываете сбои, простая упаковка __ import __ ('foo') в try / except даст вам вводящие в заблуждение результаты, если foo найден, но foo импортирует bar что не найдено .
  • find_module () не может обрабатывать имена, разделенные точками, поэтому, если вам нужно проверить, можно ли импортировать 'foo.bar.bat.baz', вы должны использовать несколько вызовов find_module и load_module согласно док.
5
ответ дан 6 December 2019 в 08:45
поделиться
Другие вопросы по тегам:

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