Попробуйте это:
class AcquisitionSerializer(serializers.ModelSerializer):
class Meta:
model = Acquisitions
fields = ('id', 'implant', 'beg_acq', 'duration_acq')
class RawDatasSerializer(serializers.ModelSerializer):
class Meta:
model = RawDatas
fields = ('id', 'data_type', 'sampling_freq', 'bin_file', 'acq')
def create(self, validated_data):
acq_data = validated_data.pop('acq')
acq = Acquisitions.objects.filter(id=acq_data.get('id')).first()
if not acq:
acq = AcquisitionSerializer.create(AcquisitionSerializer(), **acq_data)
rawdata = RawDatas.objects.create(acq=acq, **validated_data)
return rawdata
Это всегда лучше для целей обслуживания ограничить объем любого имени (быть этим функция, переменная или постоянная) так же как возможным. Таким образом, я предложил бы также
static const int BUFFER_LENGTH = 12;
или
enum { BUFFER_LENGTH = 12 };
в определении класса.
Нет большого преимущества для первого, за исключением того, что можно явно управлять типом. enum
причины C++ для выбора неуказанного интеграла, "лежащего в основе типа" для Вас - это могло быть столь же маленьким как char
если Ваше перечисление содержит только маленькие значения, хотя опытным путем, большинство компиляторов по умолчанию будет использовать int
.
Перечислить тип не предназначен для определения числовой константы, хотя это (ab), используемый для этого много в шаблонном метапрограммировании.
Если бы значение константы запутано с классом, я определил бы его там. Затем у Вас все еще есть два варианта:
class WithConst {
public:
// 1. as a const static member variable
static const int sc_nNumber = 100; // I can initialize here for
// integral-types only
// 2. as a static member function - possibly inlined.
static int sf_nNumber() { return 100; }
};
Плюс сторона из второго выбора - то, что Вы не должны изменять клиентский код позже, когда Вы хотите, например, считать константу из реестра или файла конфигурации.
Статическая членская переменная константы является лучшей - это кратко, решает проблему полностью и гарантирует, что никакие конфликты не произойдут с другими подобными классами (который довольно возможен с определением препроцессора или глобальной константой). Я предлагаю, чтобы Вы объявили это в CamelCase скорее, что во всех прописных буквах с undescores так, чтобы это не смотрело как что-то специальное, но как нормальный участник класса, который это действительно.
Я читал в "Размышлении в C++", что "перечислимый взлом" использовался в прошлом, потому что некоторые компиляторы не поддерживали "статическую константу" участники класса:
http://www.linuxtopia.org/online_books/programming_books/thinking_in_c++/Chapter08_023.html
Таким образом, если Вы используете старинный компилятор или хотите поддерживать их, используют перечислимый взлом. (Я понятия не имею, Какого возраста они должны быть для не поддержки статической константы),
Используя константу интервал может быть менее эффективным, чем использование перечисления, ниже является программой, которая демонстрирует это. Скомпилированный с Metrowerks CodeWarrior 8.x для Windows, это показывает, что объект класса, который определяет константу как интервал константы, берет 4 байта памяти больше, чем подобный класс, который определяет эту константу как перечисление:
#include <stdio.h>
#include <stdlib.h>
class foo {
enum { MY_CONST = 1 };
int x;
public:
foo();
};
class bar {
const int MY_CONST;
int x;
public:
bar();
};
int main() {
printf( "%u %u\n", sizeof( foo), sizeof( bar));
return EXIT_SUCCESS;
}
Это производит: "4 8"
Конструкторы были добавлены для предотвращения агрессивной оптимизации компилятором. Поскольку программа не создает объекты этих типов, конструкторы не должны быть на самом деле определены в модуле раздельной компиляции. То же верно для интервала константы
Я не уверен, являются ли они абсолютно взаимозаменяемыми в этом конкретном случае. Так как Вы основываете размер участника массива на константе, я полагаю, что это должно быть перечисляемое значение. У меня нет времени для поиска его в Стандарте, но я был бы удивлен, можно ли использовать int
участник как размер массива, даже если это static const
так как фактическое значение не могло бы быть видимо в заголовке.
// === in myclass.h
class MyClass {
public:
static const int MY_SIZE;
private:
int ary[MY_SIZE];
};
// === in myclass.cpp
/*static*/ const int MyClass::MY_SIZE = 10;
// === in otherclass.cpp
void OtherClass::operation(MyClass& obj) {
std::cout << "Sizeof(MyClass) = " << sizeof(obj) << std::endl;
}
Я не думаю, что компилятор может скомпилировать otherclass.cpp
не уже скомпилировав myclass.cpp
.
В большинстве других случаев я сказал бы, Идут с классом статическая постоянная опция, так как это будет участвовать немного более разумно в вычете типа и таком. Я только использую перечисленные целочисленные константы, когда я действительно должен или когда они - действительно перечислимые константы (конечно).
Я просто смотрел на Стандарт, пока я жевал далеко на ланче (Спасибо за пошаговое перемещение David)
Целочисленное константное выражение может включить только литералы (2.13), перечислители,
const
переменные или статические элементы данных интеграла или перечисляемых типов, инициализированных с константными выражениями (8.5), не введите шаблонные параметры интеграла или перечисляемых типов, иsizeof
выражения.
Это похоже на константу и перечислимый, оба будут работать при условии, что Вы обеспечиваете постоянный инициализатор в объявлении (или то определение?).
In reading previous posts i noticed that no one mentioned an "enum in a namespace" trick. If you like enums because you are working on an older compiler (I've had such experience on VxWorks/Tornado embedded programming platform), then listen up: you can avoid naming collisions by placing enum inside a namespace or (if namespaces aren't supported either) inside a class.