У меня есть некоторая нетривиальная логика, необходимая для вычисления путей к определенным каталогам исходных файлов и файлов заголовков, и, поскольку она применяется к нескольким SConscripts, я помещаю ее в отдельный файл .py, импортированный из каждого SConscript, который в ней нуждается. Теперь мне нужно иметь возможность вызывать глобальную функцию SCons (в данном случае функцию Glob
) из вспомогательного сценария. Раньше эту функцию можно было вызывать непосредственно из SConscripts, но теперь, когда мне нужно вызвать ее из отдельного вспомогательного сценария, я не могу понять, как ее вызвать. Я полагаю, что это, вероятно, тривиально, но я действительно не очень хорошо знаком с Python.
ОБНОВЛЕНИЕ:
Похоже, что возможность вызывать Glob()
как «глобальную функцию» как-то связана с некоторыми трюками, которые использует SCons. Вот выдержка из основного входного файла (SConscript.py, который не совпадает с SConscripts, которые мы приправляем по всему нашему исходному дереву):
_DefaultEnvironmentProxy = None
def get_DefaultEnvironmentProxy():
global _DefaultEnvironmentProxy
if not _DefaultEnvironmentProxy:
default_env = SCons.Defaults.DefaultEnvironment()
_DefaultEnvironmentProxy = SCons.Environment.NoSubstitutionProxy(default_env)
return _DefaultEnvironmentProxy
class DefaultEnvironmentCall(object):
"""A class that implements "global function" calls of
Environment methods by fetching the specified method from the
DefaultEnvironment's class. Note that this uses an intermediate
proxy class instead of calling the DefaultEnvironment method
directly so that the proxy can override the subst() method and
thereby prevent expansion of construction variables (since from
the user's point of view this was called as a global function,
with no associated construction environment)."""
def __init__(self, method_name, subst=0):
self.method_name = method_name
if subst:
self.factory = SCons.Defaults.DefaultEnvironment
else:
self.factory = get_DefaultEnvironmentProxy
def __call__(self, *args, **kw):
env = self.factory()
method = getattr(env, self.method_name)
return method(*args, **kw)
def BuildDefaultGlobals():
"""
Create a dictionary containing all the default globals for
SConstruct and SConscript files.
"""
global GlobalDict
if GlobalDict is None:
GlobalDict = {}
import SCons.Script # <-------This is referring to a directory with a file named __init__.py, which I've learned is something special in Python
d = SCons.Script.__dict__
def not_a_module(m, d=d, mtype=type(SCons.Script)):
return not isinstance(d[m], mtype)
for m in filter(not_a_module, dir(SCons.Script)):
GlobalDict[m] = d[m]
return GlobalDict.copy()
Поэтому я подумал, что, возможно, мне нужно import SCons.Script
в моем вспомогательном скрипте:
import SCons.Script
К сожалению, я все еще получаю это:
NameError: name 'Glob' is not defined:
File "D:\Git\......\SConstruct", line 412:
SConscript(theSconscript, duplicate=0)
File "c:\python37\lib\site-packages\scons\SCons\Script\SConscript.py", line 671:
return method(*args, **kw)
File "c:\python37\lib\site-packages\scons\SCons\Script\SConscript.py", line 608:
return _SConscript(self.fs, *files, **subst_kw)
.
.
.
File "D:\Git\........\SConscript", line 433:
.
.
.
File "D:\Git\............\PathSelector.py", line 78:
src_files.extend(Glob((os.path.join(src_path_a, '*.c')), strings=1))
@J_H Спасибо, что предложили помощь; мое обновление выше предоставляет достаточно информации?
Хм, это много одиночных шагов, не знаю, что с этим делать. Иногда l
(список), p variable
, b break_line
и c
(продолжение) хороши для краткого пропуска дюжины «скучных» строк кода, которые, как известно, хорошо работают. // Не стесняйтесь вызывать встроенный glob напрямую, если вам не нужна прокладка. Теперь давайте попробуем сфокусировать этот вопрос таким образом, чтобы участники SO могли помочь, используя стандартный шаблон: я набрал команду, я увидел это, я надеялся увидеть это.
SCons делает некоторые трюки, чтобы удалить шаблонную пластину, где это возможно, но, насколько мне известно, даже если Glob
выглядит как глобальная функция, под капотом SCons по-прежнему вызывает ее для объекта среды по умолчанию. Нет особого смысла пытаться воспроизвести эти трюки в файле *.py. Просто передайте ему среду. Возможно, я мог бы рассказать больше, если бы вы предоставили свой код и ошибку, которую вы получаете. Это было бы намного полезнее, чем выдержки из исходников SCons.
@PiotrSiupa Как мне передать среду SCons в мой код вспомогательного скрипта? Извините, может быть, это очевидно для программиста Python, но я не слишком хорошо знаком с Python.
Из справочной страницы:
Глобальные функции можно вызывать из пользовательских модулей Python, которые вы импортируете в файл SConscript, добавляя следующий импорт в модуль Python:
from SCons.Script import *
Ух ты. Спасибо, что прочитали руководство для меня. -я с красным лицом-
Не беспокойтесь об этом... это БОЛЬШАЯ справочная страница.
.
для текущего рабочего каталога), и мы будем заботиться оos.getcwd()
. Если у вас есть трассировка стека, возможно, из-за неудачногоimport
, укажите полную трассировку в своем вопросе. При отслеживании ошибок импорта вы можете обнаружить, что$ python -m site
предлагает полезные диагностические данные.