Как я могу выяснить в моем модуле, если основная программа использует определенную переменную? - PullRequest
1 голос
/ 25 февраля 2010

Я знаю, что это не звучит Pythonic, но потерпите меня на секунду.

Я пишу модуль, который зависит от внешнего модуля с закрытым исходным кодом. Этот модуль должен быть создан для использования (используя module.create ()).

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

Мои попытки до сих пор включали использование sys._getframe (). F_globals и итерацию по элементам, но в моем тестировании это не сработало. Если я создаю экземпляр модуля как modInst, а затем вызываю функцию в моем модуле, он не показывает переменную modInst. Есть ли другое решение для этого? Пример кода приведен ниже.

import sys
if moduleName not in sys.modules:
    import moduleName
    modInst = moduleName.create()
else:
    globalVars = sys._getframe().f_globals
    for key, value in globalVars:
        if value == "Module Name Instance":
            return key
    return moduleName.create()

РЕДАКТИРОВАТЬ: Пример кода включен.

Ответы [ 2 ]

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

Похоже, ваш код предполагает, что функция .create() была вызвана, если вообще, непосредственным / прямым вызывающим абонентом вашей функции (которую вы показываете только частично, что затрудняет уверенность в том, что происходит) и результаты помещаются в переменную global (модуля, в котором находится вызывающая функция вашей функции). Все это кажется довольно хрупким. Разве этот сторонний модуль не имеет своих собственных глобальных переменных, на которые влияет то, был ли вызван модуль create или нет? Я предполагаю, что это будет - где еще он хранит изменения состояния, возникающие в результате выполнения create - и я бы изучил это.

Для решения конкретной проблемы, которую вы подняли,

Я не уверен, как я могу получить имена переменных, определенных основным Программа

это просто - основная программа находится в виде модуля в sys.modules['__main__'], поэтому просто используйте vars(sys.modules['__main__']), чтобы получить глобальный словарь основной программы (имена переменных - это ключи в этом словаре, а также Конечно, с именами функций, классов и т. д. - модуль, как и любой другой модуль, имеет ровно одно пространство имен верхнего / глобального уровня, а не одно для переменных, отдельное для функций и т. 1020 *

0 голосов
/ 25 февраля 2010

Предположим, что внешний модуль с закрытыми исходными кодами называется extmod. Создать my_extmod.py:

import extmod
INSTANTIATED=False
def create(*args,**kw):
    global INSTANTIATED
    INSTANTIATED=True
    return extmod.create(*args,**kw)

Затем попросите пользователей импортировать my_extmod вместо extmod напрямую. Чтобы проверить, была ли вызвана функция create, просто проверьте значение extmod.INSTANTIATED.

Редактировать: Если вы откроете сеанс IPython и наберете import extmod, введите extmod.[TAB], тогда вы увидите все переменные верхнего уровня в пространстве имен extmod. Это может помочь вам найти какой-то параметр, который изменяется при вызове extmod.create.

Если исключить это и запретить обучать пользователей импортировать my_extmod, то, возможно, вы могли бы использовать что-то вроде функции ниже find_extmod_instance выполняет поиск по всем модулям в sys.modules.

def find_instance(cls):
    for modname in sys.modules:
        module=sys.modules[modname]
        for value in vars(module).values():
            if isinstance(value,cls):
                return value

x=find_instance(extmod.ExtmodClass) or extmod.create()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...