Чтобы различать разных типов партнеров, вы можете использовать прокси-моделей .
class PartnerManager(models.Manager):
def __init__(self, partner_type):
super().__init__()
self.partner_type = partner_type
def get_queryset(self):
return super().get_queryset().filter(typeid=self.partner_type)
class Client_Partner(Trading_Partner):
objects = PartnerManager(1)
class Meta(Trading_Partner.Meta):
proxy = True
class Parent_Partner(Trading_Partner):
objects = PartnerManager(0)
class Meta(Trading_Partner.Meta):
proxy = True
class Supplier_Partner(Trading_Partner):
objects = PartnerManager(2)
class Meta(Trading_Partner.Meta):
proxy = True
Но я не знаю, возможно ли это с неуправляемыми моделями.
Скомпилируйте обоих, посмотрите на ассемблер. Первым является тот меньше инструкции...
; 9 : std::string f("Hello");
push OFFSET ??_C@_05COLMCDPH@Hello?$AA@
lea ecx, DWORD PTR _f$[esp+80]
call DWORD PTR __imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z
; 10 : std::string g = "Hello";
push OFFSET ??_C@_05COLMCDPH@Hello?$AA@
lea ecx, DWORD PTR _g$[esp+80]
mov DWORD PTR __$EHRec$[esp+88], 0
call DWORD PTR __imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z
... но это - артефакт, потому что это было первое, которое видел компилятор. Измените код путем свопинга порядка:
; 9 : std::string g1 = "Hello";
push OFFSET ??_C@_05COLMCDPH@Hello?$AA@
lea ecx, DWORD PTR _g1$[esp+136]
call DWORD PTR __imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z
; 10 : std::string f1("Hello");
push OFFSET ??_C@_05COLMCDPH@Hello?$AA@
lea ecx, DWORD PTR _f1$[esp+136]
mov DWORD PTR __$EHRec$[esp+144], 0
call DWORD PTR __imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBD@Z
... и о чудо, вторым является тот меньше инструкции.
Мы также видим, что этот компилятор (Microsoft VC ++ 2005, настройки Release) генерировал тот же ассемблер для обеих версий. Таким образом, это не имеет никакого значения в этом компиляторе, и можно доказать его.
Другие ответы все корректны, но также помните, что это, вероятно, не имеет значения. Это будет редким, очень редким, невероятно редким, та строковая эффективность инициализации будет когда-либо влиять на скорость Вашей программы даже частью секунды.
Самим вопросом является забавный, потому что он помогает показать операции конструкторов C++ и присвоений, но на практике при пребывании в течение времени, пытаясь оптимизировать это (и отправляя на ТАК доказательство достаточно, Вы..) Вы действительно наклоняетесь в ветряных мельницах.
Лучше избежать отвлечения и потратить Ваше усилие в другом месте.
Единственная реальная разница - то, что первый технически требует использования конструктора копии, но компилятору позволяют игнорировать его так, чтобы эффективность была идентична в обоих случаях.
Однако первое требует, чтобы конструктор копии был доступным (т.е. не частным), даже если это на самом деле не используется.
Я ответил на это здесь
Одна вещь я поместил в этот ответ здесь: Ни один не использует оператора присваивания.
Короткое объяснение строки определенная вещь все же. std::string
имеет конструктора, берущего один аргумент, который принимает char const*
:
// simplified to a normal class declaration. std::string actually
// is a template instantiation.
class string {
public:
string(char const* str) {
// copy over...
}
};
Теперь Вы видите, что это имеет конструктора, берущего указатель на символ (символы). Так, чтобы это могло принять строковый литерал. Я думаю, что следующий случай очевиден затем:
string s("hello");
Это вызовет конструктора непосредственно и инициализирует s
таким образом. Это называют прямой инициализацией.
Другой способ инициализировать переменную называют инициализацией копии. В Стандарте говорится для случая инициализации копии, где инициализатор не имеет типа объекта, это инициализирует, инициализатор преобразовывается в надлежащий тип.
// uses copy initialization
string s = "hello";
Во-первых, давайте заявим типы
s
имеет станд. типа:: строка"hello"
массив, который в этом случае снова обрабатывается как указатель. Мы для этого рассмотрим это как char const*
. Компилятор ищет два способа сделать преобразование.
std::string
?Это создаст временный файл std::string
одним из тех путей, который затем используется для инициализации объекта s
при помощи std::string
конструктор копии. И это видит std::string
имеет конструктора преобразования, который принимает инициализатор. Таким образом, это использует его. В конце это - эффективно то же как
std::string s(std::string("hello"));
Обратите внимание, что форма, которая используется в Вашем примере, который инициировал все это
std::string s = "hello";
определяет неявное преобразование. Можно отметить конструктора, берущего char const*
как явный для Ваших типов, если Вы задаетесь вопросом о правилах инициализации для Вашего материала, и он не позволит использовать соответствующего конструктора в качестве конструктора преобразования больше:
class string {
public:
explicit string(char const* str) {
// copy over...
}
};
С этим, инициализируя его с помощью a copy initialization
и a char const*
на самом деле запрещается теперь (и в различных других местах)!
Теперь, это было то, если компилятор не поддерживает elision временных файлов в различных местах. Компилятору позволяют предположить, что конструктор копии копирует в этом контексте, и может устранить дополнительную копию временной строки и вместо этого создать временный станд.:: представьте в виде строки непосредственно в инициализированный объект. Однако конструктор копии должен быть доступным в частности. Так, инициализация копии недопустима, если Вы делаете это
class string {
public:
explicit string(char const* str) {
// copy over...
}
private: // ugg can't call it. it's private!
string(string const&);
};
Теперь на самом деле только прямой случай инициализации допустим.