Вызов сценариев и переменных между ними в Python итеративно - PullRequest
0 голосов
/ 22 января 2019

Я пытаюсь автоматизировать скрипт, который:

  • читает входные данные, определенные в другом сценарии (например, Input_01.py или Input_02.py, просто содержащие определение переменной, например: J = 6 или J = 7); и
  • использовать эту переменную внутри функции, т. Е .:

    def foo_function():
    
        A = J
        A += 3
        print(A)
    

Теперь, если мне не нужно ничего автоматизировать, все довольно просто: Я просто набираю from Input_01 import J и все. Затем я могу сделать то же самое для Input_02 и повторить операцию. Но моя идея состоит в том, чтобы создать сценарий (Multi_Run.py), который позволит мне автоматизировать процесс вызова несколько раз ключевого сценария (называемого «code_foo.py»), по одному для каждого входного файла, и каждый раз для чтения другого входного файла. (например, Input_01, Input_02, ... и т. д.)

Это мой текущий скрипт "Multi_Run.py" (упрощенный для случая только двух разных входных файлов):

Inputs = []
for i in range(2):
    Inputs.append("Input_0%s" % (i+1))


for Counter in Inputs:
    import code_foo
    code_foo.foo_function()

Но теперь я не могу сказать, внутри "code_foo.py", что-то вроде: from Counter import J, потому что это не сработает по двум причинам:

  1. Во-первых, Counter не является переменной в code_foo (кажется, что это можно решить, добавив строку типа from __main__ import *)
  2. Во-вторых, функция импорта не может прочитать строку внутри переменной Counter, но ей нужно непосредственно имя модуля (например, Input_01), предотвращая автоматизацию. Я попытался решить эту проблему с помощью importlib.import_module, но, похоже, он не работает должным образом (то есть модуль «Input _ ##» как-то «импортирован», но не «run», что означает, что строка «J = # somenumber») не запускается при импорте скрипта, и поэтому я получаю сообщение об ошибке, поскольку переменная J не определена).

Для большей ясности мой текущий скрипт code_foo.py выглядит следующим образом:

import importlib


from __main__ import *

importlib.import_module(Counter)


def foo_function():

        A = J
        A += 3
        print(A)

Есть намеки? большое спасибо

1 Ответ

0 голосов
/ 23 января 2019

AFAICT (ваш вопрос все еще довольно неясен), похоже, у вас есть две проблемы здесь.

Первый касается импорта и пространств имен Python. Импорт Python не включает в себя C или PHP, поэтому импорт модуля не делает имена, определенные в модуле, непосредственно доступными в пространстве имен импортера, вы должны использовать полное имя ("."). Кроме того, Python не имеет пространства имен «global global», «глобалы» Python являются глобальными только для пространства имен текущего модуля, поэтому определение глобального имени в модуле «a» не делает его волшебным образом доступным для модулей, импортируемых модулем ». а». Это означает, что ваш foo_function в code_foo.py не может напрямую обращаться к именам, определенным в вашем основном скрипте.

На самом деле - и это вторая проблема - ваша проблема исходит от foo_function в зависимости от глобального имени, которое определено в другом месте. Это ошибка дизайна. Как правило, вы не должны использовать глобалы, когда они вам не нужны, и вам очень редко нужны глобалы. Просто напишите свои функции, чтобы они принимали «внешние» значения в качестве аргумента, и все станет намного проще и намного проще для чтения, тестирования и обслуживания.

В вашем случае все, что вам нужно сделать, это 1 / переписать foo_function(), так что он принимает J в качестве аргумента и 2 / переписать multirun, чтобы он получил J из ваших «входных» модулей и передает его foo_function:

# code_foo.py

def foo_function(j):
    a = j
    a += 3
    print(a)

и

# multirun.py

import importlib
import code_foo

def main():
   inputs = ["Input_0%s" % i for i in range(1,3)]

   for modname in inputs:
       module = importlib.import_module(modname)
       j = module.J 
       code_foo.foo_function(j)

if __name__ == "__main__":
    main()

В качестве примечания: соглашения об именах в python должны использовать имена all_lower для модулей и переменных - имена ALL_CAPS для псевдоконстант.

...