Препятствуйте тому, чтобы компоновщик удалил globals

Если вы используете Python 3.x, как предложено в 159 , вы можете использовать диктант понимания, а затем создать из него DataFrame Pandas, используя имена в качестве индексов строк:

[ 110]

На самом деле, промежуточный словарь является вложенным словарем: ключи внешнего словаря являются метками строк (в данном случае это элементы списка row_names); значение, связанное с каждым ключом, представляет собой словарь, ключами которого являются метки столбцов (т. е. элементы в column_names), а значения являются соответствующими элементами в списке data.

Функция from_dict используется для создания экземпляра DataFrame.

Итак, предыдущий код дает следующий результат:

     height weight grade
jack    100     50     A
mick    107     62     B
nick    103     64     C
pick    105     78     D

12
задан Drealmer 30 April 2009 в 11:06
поделиться

4 ответа

Да, у меня тоже была эта проблема. Единственные надежные способы, которые я нашел, были:

  • превратить библиотеку в DLL

или:

  • переместить объекты регистрации в исполняемый файл

Ни один из них не идеален, хотя решение DLL в порядке если вы не возражаете против использования DLLS, мне тоже было бы интересно узнать о других решениях.

1
ответ дан 2 December 2019 в 22:38
поделиться

Если вы находитесь в среде UNIX, то при вызове ld с параметром whole-archive все объектные файлы будут включены в статическую библиотеку независимо от использования.

1
ответ дан 2 December 2019 в 22:38
поделиться

Ознакомьтесь с ответом на «Лучший способ создать список данных по типу»

. Здесь есть два ключевых важных понятия. Во-первых:

(void) register_object;  

использует объект, чтобы убедиться, что компоновщик не удаляет его, и,

template<typename D> typename automatic_register<D>::exec_register 
    automatic_register<D>::register_object;

гарантирует, что статический глобал выделяется для каждого экземпляра. Вы должны хранить свои данные в этом объекте. Он немного отличается тем, что для каждого объекта, а не для класса, но если вы адаптируете свой макрос для создания

// Global list of objectsh
struct FpList
{
   FpList( FuncPtr func ) :
      func(func)
   {
      head = next;
      next = this
   }
   FpList* next;
   FuncPtr func;

   static FpList* head;
};
// In .cxx:
FpList* FpList::head = 0;  

, тогда модифицируйте ваш зарегистрированный макрос так, чтобы REGISTER (Foo), чтобы он создавал:

struct register_Foo : FpList
{
   register_Foo( FuncPtr fn ): FpList(fn)
   {
      (void) register_object;  
   }
   static register_Foo register_object;
};

Я думаю, что это не так достаточно. Вам все еще нужно создать экземпляр шаблона, передать if & Foo и убедиться, что экземпляр

register_Foo register_Foo::register_object

где-то создан. Код шаблона для Automatic_register показывает, как это сделать в заголовке. Если вы можете поместить свой макрос в .cxx, просто объявите:

register_Foo register_Foo::register_object( &Foo );

как часть вашего макроса. Я думаю, что это может сработать. (все по памяти, так что кто знает).

1
ответ дан 2 December 2019 в 22:38
поделиться

Похоже, вы уже знакомы с некоторыми недостатками и преимуществами.

Некоторые другие: a) Делает возможным поддерживать правильную оптимизацию хвостового вызова, даже если базовая реализация не поддерживает ее б) Легче создавать такие вещи, как "трассировка стека" на уровне языка. c) Проще добавить правильные продолжения, как вы отметили

. Недавно я написал простой интерпретатор "Scheme" на C #, который изначально использовал стек .NET. Затем я переписал его, чтобы использовать явный стек - так что, возможно, вам поможет следующее:

В первой версии использовался неявный стек времени выполнения .NET ...

Первоначально это была просто иерархия классов с разными формы (Lambda, Let и т. д.) являются реализациями следующего интерфейса:

// A "form" is an expression that can be evaluted with
// respect to an environment
// e.g.
// "(* x 3)"
// "x"
// "3"
public interface IForm
{
    object Evaluate(IEnvironment environment);
}

IEnvironment выглядела так, как и следовало ожидать:

/// <summary>
/// Fundamental interface for resolving "symbols" subject to scoping.
/// </summary>
public interface IEnvironment
{
    object Lookup(string name);
    IEnvironment Extend(string name, object value);
}

Для добавления «встроенных функций» к моему интерпретатору схемы у меня изначально был следующий интерфейс:

/// <summary>
/// A function is either a builtin function (i.e. implemented directly in CSharp)
/// or something that's been created by the Lambda form.
/// </summary>
public interface IFunction
{
    object Invoke(object[] args);
}

Это было тогда, когда он использовал неявный стек времени выполнения .NET. Кода определенно было меньше, но было невозможно добавить такие вещи, как правильная рекурсия хвоста, и, что наиболее важно, моему интерпретатору было неудобно иметь возможность предоставить "

3
ответ дан 2 December 2019 в 22:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: