Ленивая оценка в Python? Между модулями? - PullRequest
2 голосов
/ 08 февраля 2010

Я не уверен, возможно ли что-то подобное в Python, но если это так, это было бы действительно полезно (по крайней мере, для меня в данном случае).

У меня есть тестовая среда, в которой я хочу отделить тестовую конфигурацию от тестовых команд. Это полезно, потому что позволяет смешивать и сопоставлять конфигурации / тесты, фактически не изменяя код. По сути, у меня просто есть сценарий для короткого запуска, который берет имена модуля конфигурации и тестового модуля, затем загружает и запускает оба, например, так:

config = __import__(configmod)
test = __import__(commandsmod)

config.run(test.commands)

Единственная проблема с этим заключается в том, что я бы хотел, чтобы тестовый скрипт имел ограниченную осведомленность о параметрах конфигурации. В идеале я хотел бы иметь возможность сделать что-то вроде следующего в модуле test / commands:

command1 = MyCommand(arg1, arg2, LazyArg1())
command2 = MyCommand(arg1, arg2, LazyArg2())
commands = [command1, command2]

где LazyArg1 и LazyArg2 - это методы, которые определены в модуле конфигурации (или в модуле бегуна, который импортирует обе команды config /). Есть ли способ отложить оценку этих функций до тех пор, пока они действительно не будут определены?

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

Ответы [ 2 ]

1 голос
/ 08 февраля 2010

Python динамически набирается, так что в этом нет ничего особенного

configMod.py:

##### this is configMod.py #####
modTestArg1 = "Brian"

def runTest(testMod, *args, **kwargs):
    testMod.doTest(*args, **kwargs)

testMod.py:

##### this is testMod.py #####
def doTest(name, address, city="San Francisco"):
    print "doTest called with name: %s, address: %s, city: %s" % \
        (name, address, city)

controlMod.py

##### this is controlMod.py #####
import configMod
import testMod

configMod.runTest(testMod, configMod.modTestArg1, "123 Fake Street")

Запустите его:

python controlMod.py
doTest called with name: Brian, address: 123 Fake Street, city: San Francisco
0 голосов
/ 08 февраля 2010

Я не хочу отвечать на свой вопрос, но, подумав, я нашел потенциальное решение (хотя я бы хотел услышать другие идеи).

Предположим, у нас есть модуль mod1:

def myfunc(z):
    return z

и модуль mod2:

x = lambda mod: mod.myfunc

Теперь вы можете сделать следующее в третьем модуле:

import mod1
from mod2 import *

x(mod1)(5)

и в итоге вы звоните mod1 myfunc. Если двойной вызов функции сбивает с толку, вы можете присвоить x(mod1) имени другой переменной.

...