Распределение объектов Python C-API

== выполняет контрольную проверку равенства, ссылаясь на то, что 2 объекта (строки в этом случае) относятся к одному и тому же объекту в памяти.

Метод equals() будет проверять, будет ли содержимое или состояния двух объектов одинаковы.

Очевидно, что == работает быстрее, но во многих случаях может (может) давать ложные результаты, если вы просто хотите сказать, имеет ли 2 String s тот же текст.

Определенно рекомендуется использовать метод equals().

Не беспокойтесь о производительности. Некоторые способы поощрения использования String.equals():

  1. Реализация String.equals() сначала проверяет ссылочное равенство (используя ==), и если две строки одинаковы по ссылке, дальнейший расчет Выполняется!
  2. Если 2 ссылки на строки не совпадают, String.equals() будет проверять длину строк. Это также является быстрой операцией, поскольку класс String хранит длину строки, не нужно считать символы или кодовые точки. Если длины отличаются, дальнейшая проверка не выполняется, мы знаем, что они не могут быть равными.
  3. Только если мы доберемся до этого, будет фактически сопоставлено содержимое двух строк, и это будет короткий сравнение: не все символы будут сравниваться, если мы найдем несоответствующий символ (в том же положении в 2 строках), никакие другие символы не будут проверены.

Когда все сказано и даже если у нас есть гарантия, что строки являются стажерами, использование метода equals() все еще не является издержками, которые можно было бы подумать, определенно рекомендуемым способом. Если вам нужна эффективная проверка ссылок, используйте перечисления, где гарантируется спецификацией и реализацией языка, что одно и то же значение перечисления будет одним и тем же объектом (по ссылке).

7
задан Cœur 27 October 2018 в 07:41
поделиться

2 ответа

Документация для них в http://docs.python.org/3.0/c-api/typeobj.html и , http://docs.python.org/3.0/extending/newtypes.html описывает, как сделать Ваш собственный тип.

tp_alloc делает выделение памяти низкого уровня для экземпляра. Это эквивалентно malloc (), плюс инициализируют refcnt к 1. Python имеет свое собственное средство выделения, PyType_GenericAlloc, но тип может реализовать специализированное средство выделения.

tp_new совпадает с Python __ новый __. Это обычно используется для неизменных объектов, где данные хранятся в самом экземпляре, по сравнению с указателем на данные. Например, строки и кортежи хранят свои данные в экземпляре, вместо того, чтобы использовать символ * или PyTuple *.

Для этого случая, tp_new выясняет, сколько памяти необходимо, на основе входных параметров, и называет tp_alloc для получения памяти, затем инициализирует существенные поля. tp_new не должен называть tp_alloc. Это может, например, возвратить кэшируемый объект.

tp_init совпадает с Python __ init __. Большая часть Вашей инициализации должна быть в этой функции.

различие между __ новый __ и __ init __ называют двухэтапная инициализация , или двухфазная инициализация .

Вы говорите" , C++ просто имеет новый ", но это не корректно. tp_alloc соответствует, пользовательское средство выделения арены в C++, __ новый __ соответствует пользовательскому средству выделения типа (функция фабрики), и __ init __ больше похож на конструктора. Та последняя ссылка обсуждает больше о параллелях между стилем Python и C++.

Также читает http://www.python.org/download/releases/2.2/descrintro/ для получения дополнительной информации о том, как __ новый __ и __ init __ взаимодействуют.

Вы пишете, что хотите "создать объект непосредственно в C++". Это довольно трудно, потому что самое меньшее необходимо будет преобразовать любые исключения Python, которые произошли во время объектного инстанцирования в исключение C++. Вы могли бы попытаться смотреть на Повышение:: Python для некоторой справки с этой задачей. Или можно использовать двухфазную инициализацию. ;)

11
ответ дан gwk 27 October 2018 в 17:41
поделиться
  • 1
    @Zainodis, heh да, я нахожу подобными языкам C, чтобы быть почти универсальным языком, если используется от действительно высокого уровня! – Blindy 2 May 2012 в 01:52

Я не знаю API Python вообще, но если Python разделяет выделение и инициализацию, необходимо смочь использовать новое размещение.

, например:

 // tp_alloc
 void *buffer = new char[sizeof(MyExtensionObject)];
 // tp_init or tp_new (not sure what the distinction is there)
 new (buffer) MyExtensionObject(args);
 return static_cast<MyExtensionObject*>(buffer);

 ...
 // tp_del
 myExtensionObject->~MyExtensionObject(); // call dtor
 // tp_dealloc (or tp_free? again I don't know the python apis)
 delete [] (static_cast<char*>(static_cast<void*>(myExtensionObject)));
0
ответ дан Logan Capaldo 27 October 2018 в 17:41
поделиться
  • 1
    Пока я соглашаюсь со всем, что Вы записали выше, Доктрина 2 сознательно очень легка, по сравнению с предыдущей версией. Если OP ожидает поведения they' ll быть разочарованным. Нуждается в полном исследовании для понимания то, что Вы получаете и из чего Вы сортируете, проигрывают (или должен сделать очень по-другому). – Orbling 26 July 2011 в 12:13
Другие вопросы по тегам:

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