PyEval_GetGlobals()
을 사용하여 외부 범위에 액세스 할 수 있습니다. PyEval_GetGlobals()
은 현재 실행의 전역 변수 사전 인 프레임을 반환합니다. 파이썬 내장 함수 인 globals()
함수와 매우 유사합니다.이 함수는 함수가 정의 된 모듈의 전역 심볼 테이블을 반환합니다. 그러나 프레임 스택은 표준 모듈과 확장 모듈간에 약간 다르게 처리됩니다. 확장 모듈의 경우 현재 실행 프레임이 호출자이므로 PyEval_GetGlobals()
은 확장 모듈의 전역이 아닌 호출자 모듈의 전역 심볼을 반환합니다.
대체 한 후, PyEval_GetFrame()
통해 현재 프레임에 대한 핸들을 얻을 수있는 각 프레임 의 (f_local
) 로컬 및 글로벌 (f_global
) 사전 검사 스택으로 걷는다. 여기
기술은 그들 사이의 미묘한 차이를 모두 보여주는 전체 최소 일례이다. 예에서
get_global()
은
PyEval_GetGlobals()
을 사용하고
search_stack_locals()
은 스택의 각 프레임에 대한 로컬 사전을 검사합니다.
spam.py
에서
#include <boost/python.hpp>
namespace detail {
/// @brief Return a handle to a global variable. If one is not found, then
/// None is returned.
boost::python::object get_global(std::string name)
{
// Borrow a reference from the locals dictionary to create a handle.
// If PyEval_GetGlobals() returns NULL, then Boost.Python will throw.
namespace python = boost::python;
python::dict globals(python::borrowed(PyEval_GetGlobals()));
return globals.get(name);
}
/// @brief Search through the call stack for a variable. If found, the
/// object is returned. Otherwise, None.
boost::python::object search_stack_locals(std::string name)
{
// Get a handle to the current frame.
namespace python = boost::python;
python::object frame(python::borrowed(
reinterpret_cast<PyObject*>(PyEval_GetFrame())));
// Iterate through the stack's frames until the variable has been found
// or the stack has been exhausted.
while (frame)
{
// If the current frame has the desired variable, then return it.
python::dict locals(frame.attr("f_locals"));
if (locals.has_key(name))
{
return locals.get(name);
}
// Move up the stack.
frame = frame.attr("f_back");
}
// Return None
return python::object();
}
} // namespace detail
/// @brief Mockup function to demonstrate finding non-local variables.
boost::python::object cppfun(std::string name)
{
return boost::python::make_tuple(
detail::get_global(name), detail::search_stack_locals(name));
}
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
python::def("cppfun", &cppfun);
}
:
import example
x = 'spam.global.x'
y = 'spam.global.y'
def inner():
for name in ('x', 'y', 'z'):
print name, example.cppfun(name)
def outer():
x = 'spam.outer.x'
inner()
대화 형 사용 :
>>> x = 'main.global.x'
>>> y = 'main.global.y'
>>> z = 'main.global.z'
>>> import spam
>>> spam.outer()
x ('spam.global.x', 'spam.outer.x')
y ('spam.global.y', 'main.global.y')
z (None, 'main.global.z')
를 적어 둡니다 PyEval_GetGlobals()
를 사용하는 경우, example
확장 모듈 호출자의 모듈의 전역 심볼 테이블 (spam
)을 사용하는 것이다. 인터프리터의 주요 네임 스페이스에서 선언 된 전역은 스택을 반복 할 때만 발견되었습니다.