Я вызвал 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);
}
}
Из 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 имеет только классы нового стиля.
Независимо от того, являетесь ли вы подклассом из
blockquote>object
или нет, классы являются новыми в Python 3.
Важные изменения поведения между старыми и новыми классами стиля
Exception
(пример ниже) __slots__
Добавлено Это было упомянуто в других ответах, но здесь приведен конкретный пример разницы между классическим 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
Классы нового стиля наследуют от object
и должны быть записаны как таковые в Python 2.2 и далее (т. е. class Classname(object):
вместо class Classname:
). Основное изменение заключается в унификации типов и классов, и хороший побочный эффект этого заключается в том, что он позволяет наследовать от встроенных типов.
Прочтите descrintro для получения более подробной информации .
Новые классы стиля могут использовать super(Foo, self)
, где Foo
является классом, а self
является экземпляром.
super(type[, object-or-type])
Возвращает прокси-объект что метод делегатов вызывает класс родительского или родственного класса. Это полезно для доступа к унаследованным методам, которые были переопределены в классе. Порядок поиска аналогичен тому, который используется getattr (), за исключением того, что сам тип пропускается.
blockquote>И в Python 3.x вы можете просто использовать
super()
внутри класса без параметров .
Гвидо написал «Внутренняя история о классах нового стиля» , действительно отличная статья о классе нового стиля и старого стиля в Python.
Python 3 имеет только новые -style class, даже если вы пишете «класс старого стиля», он неявно получен из object
.
В классах нового стиля есть некоторые дополнительные функции, отсутствующие в классах старого стиля, такие как super
и новый C3 mro , некоторые магические методы и т. д.
Декларация:
Классы нового стиля наследуются от объекта или из другого класса нового стиля.
class NewStyleClass(object):
pass
class AnotherNewStyleClass(NewStyleClass):
pass
В классах старого стиля нет.
class OldStyleClass():
pass
object
.
– aaronasterling
22 December 2010 в 00:53
class AnotherOldStyleClass: pass
– abc
20 August 2013 в 21:23
class A: pass
и class A(): pass
строго эквивалентны. Первое средство "A не наследует ни одного родительского класса" i>, а второе средство "A наследует никакого родительского класса" i>. Это очень похоже на not is
и is not
– eyquem
21 December 2013 в 01:21
Или, вернее, вы всегда должны использовать классы нового стиля, , если у вас нет кода, который должен работать с версиями Python старше 2.2.
Классы старого стиля все еще немного быстрее для поиска атрибутов. Это обычно не важно, но может быть полезно в высокопроизводительном коде 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
%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
Вот очень практичная, истинная / ложная разница. Единственная разница между двумя версиями следующего кода заключается в том, что во второй версии 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>
>>>
_names_cache
- словарь, который кэширует (сохраняет для последующего поиска) каждое имя, которое вы переходите на Person.__new__
. Метод setdefault (определенный в любом словаре) принимает два аргумента: ключ и значение. Если ключ находится в dict, он вернет свое значение. Если он не находится в dict, он сначала установит значение, переданное в качестве второго аргумента, а затем вернет его.
– ychaouche
22 January 2014 в 23:53
__new__()
всегда вызывается, и он всегда создает новый объект, а затем выдает его. В этом случае if
предпочтительнее .setdefault()
.
– Amit Upadhyay
8 July 2015 в 10:56
__new__
на самом деле не вещь для классов старого стиля, она не используется в построении экземпляра (это просто случайное имя, которое выглядит особенным, например, определение __spam__
). Таким образом, построение класса старого стиля вызывает __init__
только в том случае, если конструкция нового стиля вызывает __new__
(объединение одного экземпляра по имени), а __init__
- его инициализацию.
– ShadowRanger
24 March 2017 в 20:20
type(x)
. Если я не подклассифицирую встроенный тип, то, похоже, нет никакого преимущества, которое я могу видеть в классах нового стиля. Существует недостаток, который является дополнительной типизацией(object)
. – recursive 3 May 2011 в 13:45super()
, не работают в классах старого стиля. Не говоря уже о том, что, как говорится в этой статье, существуют фундаментальные исправления, такие как MRO, и специальные методы, что является более чем веской причиной для его использования. – John Doe 8 December 2011 в 19:04