& lt; type 'classobj' & gt; или & lt; тип 'type' & gt; [Дубликат]

Я вызвал ContextCompat.startForegroundService(this, intent), чтобы запустить службу, затем

В службе onCreate

 @Override
 public void onCreate() {
        super.onCreate();

        if (Build.VERSION.SDK_INT >= 26) {
            String CHANNEL_ID = "my_channel_01";
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
                    "Channel human readable title",
                    NotificationManager.IMPORTANCE_DEFAULT);

            ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);

            Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
                    .setContentTitle("")
                    .setContentText("").build();

            startForeground(1, notification);
        }
}
857
задан laike9m 5 August 2015 в 10:31
поделиться

9 ответов

Из http://docs.python.org/2/reference/datamodel.html#new-style-and-classic-classes :

Вверх для Python 2.1 были использованы только классы старого стиля.

Концепция (старомодный) класс не имеет отношения к понятию типа: если x является экземпляром старый класс, тогда x.__class__ обозначает класс x, но type(x) всегда <type 'instance'>.

Это отражает тот факт, что все экземпляры старого стиля, независимо от их класса, реализованы с помощью одного встроенного типа, называемого экземпляром.

Классы нового стиля были введены в Python 2.2 для унификации понятий класса и типа. Класс нового стиля - это просто определяемый пользователем тип, не более, не менее.

Если x является экземпляром класса нового стиля, тогда type(x) обычно совпадает с x.__class__ (хотя это не гарантировано - экземпляру класса нового стиля разрешено переопределять значение, возвращенное для x.__class__).

Основная мотивация для введения классов нового стиля заключается в предоставлении единой объектной модели с полная метамодель.

Он также имеет ряд непосредственных преимуществ, таких как возможность подкласса большинства встроенных типов или введение «дескрипторов», которые позволяют вычисленные свойства.

По соображениям совместимости , классы по-прежнему по-старому.

Классы нового стиля создаются путем указания другого класса нового стиля (например, типа) в качестве родительского класса или объекта «тип верхнего уровня», если никакой другой родитель не нужен.

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

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

Python 3 имеет только классы нового стиля.

Независимо от того, являетесь ли вы подклассом из object или нет, классы являются новыми в Python 3.

487
ответ дан 9 revs, 6 users 56% 21 August 2018 в 04:32
поделиться
  • 1
    Ни одно из этих различий не является убедительным основанием для использования классов нового стиля, но все говорят, что вы всегда должны использовать новый стиль. Если я использую утиную печать, как я должен, мне никогда не нужно использовать type(x). Если я не подклассифицирую встроенный тип, то, похоже, нет никакого преимущества, которое я могу видеть в классах нового стиля. Существует недостаток, который является дополнительной типизацией (object). – recursive 3 May 2011 в 13:45
  • 2
    Некоторые функции, такие как super(), не работают в классах старого стиля. Не говоря уже о том, что, как говорится в этой статье, существуют фундаментальные исправления, такие как MRO, и специальные методы, что является более чем веской причиной для его использования. – John Doe 8 December 2011 в 19:04
  • 3
    @Tom, пример в этом ответе: stackoverflow.com/a/1203997/116 – Mark Harrison 21 December 2011 в 00:13
  • 4
    @User: классы старого стиля ведут себя одинаково во 2.7, как и в 2.1, и, поскольку мало кто даже помнит причуды, и в документации больше не обсуждается большинство из них, они еще хуже. В приведенной выше цитате документации сказано следующее: есть «исправления» и т. Д. которые не могут быть реализованы в классах старого стиля. Если вы не хотите столкнуться с причудами, с которыми никто еще не сталкивался с Python 2.1, и что документация больше не объясняет, не используйте классы старого стиля. – abarnert 7 January 2013 в 08:30
  • 5
    Вот пример причуды, на которую вы можете наткнуться, если вы используете классы старого стиля в версии 2.7: bugs.python.org/issue21785 – KT. 17 June 2014 в 09:18

Важные изменения поведения между старыми и новыми классами стиля

  • super добавлено
  • MRO изменено (объяснено ниже)
  • дескрипторы добавлены
  • объекты класса нового стиля не могут быть подняты, если не получены из Exception (пример ниже)
  • __slots__ Добавлено

MRO (порядок разрешения метода) изменено

Это было упомянуто в других ответах, но здесь приведен конкретный пример разницы между классическим MRO и C3 MRO ( используется в новых классах стилей).

Вопрос заключается в порядке поиска атрибутов (включая методы и переменные-члены) при множественном наследовании.

Классические классы сначала делают глубину поиск слева направо. Остановка в первом матче. У них нет атрибута __mro__.

class C: i = 0
class C1(C): pass
class C2(C): i = 2
class C12(C1, C2): pass
class C21(C2, C1): pass

assert C12().i == 0
assert C21().i == 2

try:
    C12.__mro__
except AttributeError:
    pass
else:
    assert False

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

class C(object): i = 0
class C1(C): pass
class C2(C): i = 2
class C12(C1, C2): pass
class C21(C2, C1): pass

assert C12().i == 2
assert C21().i == 2

assert C12.__mro__ == (C12, C1, C2, C, object)
assert C21.__mro__ == (C21, C2, C1, C, object)

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

Вокруг Python 2.5 можно было бы увеличить множество классов, в то время как Python 2.6 был удален. На Python 2.7.3:

# OK, old:
class Old: pass
try:
    raise Old()
except Old:
    pass
else:
    assert False

# TypeError, new not derived from `Exception`.
class New(object): pass
try:
    raise New()
except TypeError:
    pass
else:
    assert False

# OK, derived from `Exception`.
class New(Exception): pass
try:
    raise New()
except New:
    pass
else:
    assert False

# `'str'` is a new style object, so you can't raise it:
try:
    raise 'str'
except TypeError:
    pass
else:
    assert False
195
ответ дан Community 21 August 2018 в 04:32
поделиться
  • 1
    Хорошее четкое резюме, спасибо. Когда вы говорите «трудно объяснить по-английски», Я думаю, что вы описываете поиск по умолчанию после первого порядка, в отличие от класса старого стиля, который использует предварительный поиск по глубине. (preorder означает, что мы ищем себя перед нашим первым ребенком и послепользователем, значит, мы ищем себя после нашего последнего ребенка). – Steve Carter 5 October 2016 в 09:20

Классы нового стиля наследуют от object и должны быть записаны как таковые в Python 2.2 и далее (т. е. class Classname(object): вместо class Classname:). Основное изменение заключается в унификации типов и классов, и хороший побочный эффект этого заключается в том, что он позволяет наследовать от встроенных типов.

Прочтите descrintro для получения более подробной информации .

7
ответ дан Francesco Montesano 21 August 2018 в 04:32
поделиться

Новые классы стиля могут использовать super(Foo, self), где Foo является классом, а self является экземпляром.

super(type[, object-or-type])

Возвращает прокси-объект что метод делегатов вызывает класс родительского или родственного класса. Это полезно для доступа к унаследованным методам, которые были переопределены в классе. Порядок поиска аналогичен тому, который используется getattr (), за исключением того, что сам тип пропускается.

И в Python 3.x вы можете просто использовать super() внутри класса без параметров .

4
ответ дан jamylak 21 August 2018 в 04:32
поделиться

Гвидо написал «Внутренняя история о классах нового стиля» , действительно отличная статья о классе нового стиля и старого стиля в Python.

Python 3 имеет только новые -style class, даже если вы пишете «класс старого стиля», он неявно получен из object.

В классах нового стиля есть некоторые дополнительные функции, отсутствующие в классах старого стиля, такие как super и новый C3 mro , некоторые магические методы и т. д.

30
ответ дан Jason Sundram 21 August 2018 в 04:32
поделиться

Декларация:

Классы нового стиля наследуются от объекта или из другого класса нового стиля.

class NewStyleClass(object):
    pass

class AnotherNewStyleClass(NewStyleClass):
    pass

В классах старого стиля нет.

class OldStyleClass():
    pass
282
ответ дан Mark Harrison 21 August 2018 в 04:32
поделиться
  • 1
    если класс нового стиля наследуется от другого класса нового стиля, то по расширению он наследует от object. – aaronasterling 22 December 2010 в 00:53
  • 2
    Является ли это неправильным примером класса python старого стиля? class AnotherOldStyleClass: pass – abc 20 August 2013 в 21:23
  • 3
    @abc Я считаю, что class A: pass и class A(): pass строго эквивалентны. Первое средство "A не наследует ни одного родительского класса" , а второе средство "A наследует никакого родительского класса" . Это очень похоже на not is и is not – eyquem 21 December 2013 в 01:21
  • 4
    Так же, как и примечание, для 3.X наследование «объекта» (это означает, что у нас нет способа не наследовать «объект» в 3.X). Для причины обратной совместимости неплохо сохранить «(объект)», там все же. – Yo Hsiao 14 April 2014 в 03:32
  • 5
    Если мы собираемся получить техническую информацию о наследуемых классах, в этом ответе следует отметить, что вы создаете еще один класс старого стиля, наследуя от старого класса стиля. (Как написано, этот ответ оставляет вопрос пользователя, можно ли наследовать из класса старого стиля. Вы можете.) – jpmc26 17 September 2014 в 18:56

Или, вернее, вы всегда должны использовать классы нового стиля, , если у вас нет кода, который должен работать с версиями Python старше 2.2.

3
ответ дан Tony Meyer 21 August 2018 в 04:32
поделиться

Классы старого стиля все еще немного быстрее для поиска атрибутов. Это обычно не важно, но может быть полезно в высокопроизводительном коде Python 2.x:

In [3]: class A:
   ...:     def __init__(self):
   ...:         self.a = 'hi there'
   ...: 

In [4]: class B(object):
   ...:     def __init__(self):
   ...:         self.a = 'hi there'
   ...: 

In [6]: aobj = A()
In [7]: bobj = B()

In [8]: %timeit aobj.a
10000000 loops, best of 3: 78.7 ns per loop

In [10]: %timeit bobj.a
10000000 loops, best of 3: 86.9 ns per loop
34
ответ дан xioxox 21 August 2018 в 04:32
поделиться
  • 1
    Интересно, что вы заметили на практике, я просто прочитал, что это потому, что классы нового стиля, когда они нашли атрибут в экземпляре dict, должны выполнить дополнительный поиск, чтобы выяснить, является ли это описанием, т. Е. Имеет get , который необходимо вызвать, чтобы получить возвращаемое значение. Классы старого стиля просто возвращают найденный объект без дополнительных вычислений (но затем не поддерживают дескрипторы). Вы можете прочитать больше в этом превосходном сообщении Guido python-history.blogspot.co.uk/2010/06/… , в частности раздел в слотах – xuloChavez 20 March 2012 в 18:58
  • 2
    не похоже на CPython 2.7.2: %timeit aobj.a 10000000 loops, best of 3: 66.1 ns per loop %timeit bobj.a 10000000 loops, best of 3: 53.9 ns per loop – Benedikt Waldvogel 25 March 2012 в 00:38
  • 3
    Еще быстрее для aobj в CPython 2.7.2 на x86-64 Linux для меня. – xioxox 5 April 2012 в 13:49
  • 4
    Вероятно, это плохая идея полагаться на чистый код Python для приложений с высокой чувствительностью. Никто не говорит: «Мне нужен быстрый код, поэтому я буду использовать классы Python старого стиля». Numpy не считается чистым Python. – Phillip Cloud 30 June 2012 в 23:42
  • 5
    также в IPython 2.7.6, это не так. '' '' 477 нс против 456 нс за цикл '' '' – kmonsoor 20 July 2014 в 12:48

Вот очень практичная, истинная / ложная разница. Единственная разница между двумя версиями следующего кода заключается в том, что во второй версии Person наследует объект. Кроме того, две версии идентичны, но имеют разные результаты:

1) классы старого стиля

class Person():
    _names_cache = {}
    def __init__(self,name):
        self.name = name
    def __new__(cls,name):
        return cls._names_cache.setdefault(name,object.__new__(cls,name))

ahmed1 = Person("Ahmed")
ahmed2 = Person("Ahmed")
print ahmed1 is ahmed2
print ahmed1
print ahmed2


>>> False
<__main__.Person instance at 0xb74acf8c>
<__main__.Person instance at 0xb74ac6cc>
>>>

2) классы нового стиля

class Person(object):
    _names_cache = {}
    def __init__(self,name):
        self.name = name
    def __new__(cls,name):
        return cls._names_cache.setdefault(name,object.__new__(cls,name))

ahmed1 = Person("Ahmed")
ahmed2 = Person("Ahmed")
print ahmed2 is ahmed1
print ahmed1
print ahmed2

>>> True
<__main__.Person object at 0xb74ac66c>
<__main__.Person object at 0xb74ac66c>
>>>
17
ответ дан ychaouche 21 August 2018 в 04:32
поделиться
  • 1
    что делает «_names_cache»? Не могли бы вы поделиться ссылкой? – Muatik 22 January 2014 в 17:03
  • 2
    _names_cache - словарь, который кэширует (сохраняет для последующего поиска) каждое имя, которое вы переходите на Person.__new__. Метод setdefault (определенный в любом словаре) принимает два аргумента: ключ и значение. Если ключ находится в dict, он вернет свое значение. Если он не находится в dict, он сначала установит значение, переданное в качестве второго аргумента, а затем вернет его. – ychaouche 22 January 2014 в 23:53
  • 3
    Использование неверно. Идея состоит в том, чтобы не создавать новый объект, если он уже существует, но в вашем случае __new__() всегда вызывается, и он всегда создает новый объект, а затем выдает его. В этом случае if предпочтительнее .setdefault(). – Amit Upadhyay 8 July 2015 в 10:56
  • 4
    Но я не понял, почему разница в выходе, то есть в старом классе стилей, два экземпляра были разными, поэтому возвращались False, но в новом классе стиля оба экземпляра одинаковы. Как ? Каково изменение в классе нового стиля, что сделало два экземпляра одинаковыми, что не было в стиле старого стиля? – Pabitra Pati 27 October 2016 в 02:31
  • 5
    @PabitraPati: Это своего рода дешевая демонстрация здесь. __new__ на самом деле не вещь для классов старого стиля, она не используется в построении экземпляра (это просто случайное имя, которое выглядит особенным, например, определение __spam__). Таким образом, построение класса старого стиля вызывает __init__ только в том случае, если конструкция нового стиля вызывает __new__ (объединение одного экземпляра по имени), а __init__ - его инициализацию. – ShadowRanger 24 March 2017 в 20:20
Другие вопросы по тегам:

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