https://docs.oracle.com/javase/8/docs/platform/serialization/spec/serialTOC.html
Сериализация по умолчанию несколько многословна и предполагает максимально возможный сценарий использования сериализованного объекта, и, соответственно, формат по умолчанию (Serializable) аннотирует результирующий поток с информацией о классе сериализованного объекта.
Внешняя подача дает разработчику полный поток объектов точные метаданные класса (если таковые имеются) за минимально необходимой идентификацией класса (например, его имя). Это явно желательно в определенных ситуациях, таких как закрытые среды, в которых сопоставляются производитель потока объектов и его потребителя (который подтверждает объект из потока), а дополнительные метаданные о классе не имеют никакой цели и ухудшают производительность.
Дополнительно (как указано Uri) экстернализация также обеспечивает полный контроль над кодированием данных в потоке, соответствующем типам Java. Для (надуманного) примера вы можете записать логическое значение true, как «Y», а false - «N». Вы можете сделать это вовне.
Я действительно не вижу потребность, поскольку модуль с функциями (и не класс) служил бы хорошо в качестве одиночного элемента. Все его переменные были бы связаны с модулем, который нельзя было инстанцировать неоднократно так или иначе.
, Если Вы действительно хотите использовать класс, нет никакого способа создать частные классы или частных конструкторов в Python, таким образом, Вы не можете защитить от нескольких инстанцирований, кроме только с помощью соглашения, используемого из Вашего API. Я все еще просто поместил бы методы в модуль и рассмотрел бы модуль как одиночный элемент.
Шаблон "одиночка" реализован с любезностью Python ActiveState.
похоже, что прием должен поместить класс, это, как предполагается, только имеет один экземпляр в другом классе.
Существуют также некоторые интересные статьи о блоге Google Testing, обсуждая, почему одиночный элемент/может быть плохим и является антишаблоном:
Одно время, которое я записал одиночному элементу в Python, я использовал класс, где все функции членства имели classmethod декоратора.
class foo:
x = 1
@classmethod
def increment(cls, y = 1):
cls.x += y
Быть относительно в новинку для Python, я не уверен, какова наиболее распространенная идиома, но самая простая вещь, о которой я могу думать, просто использует модуль вместо класса. Что было бы методами экземпляра для Вашего класса, становятся просто функциями в модуле, и любые данные просто становятся переменными в модуле вместо членов класса. Я подозреваю, что это - подход pythonic к решению типа проблемы, для которой люди используют одиночные элементы.
, Если Вы действительно хотите singleton-класс, существует разумная реализация, описанная на первый хит на Google для "одиночного элемента Python", конкретно:
class Singleton:
__single = None
def __init__( self ):
if Singleton.__single:
raise Singleton.__single
Singleton.__single = self
, Который, кажется, добивается цели.
Подход модуля работает хорошо. Если мне абсолютно нужен одиночный элемент, я предпочитаю подход Метакласса.
class Singleton(type):
def __init__(cls, name, bases, dict):
super(Singleton, cls).__init__(name, bases, dict)
cls.instance = None
def __call__(cls,*args,**kw):
if cls.instance is None:
cls.instance = super(Singleton, cls).__call__(*args, **kw)
return cls.instance
class MyClass(object):
__metaclass__ = Singleton
Немного отличающийся подход для реализации одиночного элемента в Python borg шаблон Alex Martelli (сотрудник Google и гений Python).
class Borg:
__shared_state = {}
def __init__(self):
self.__dict__ = self.__shared_state
Так вместо того, чтобы вынудить все экземпляры иметь те же идентификационные данные, они совместно используют состояние.
Вот пример от Python IAQ Peter Norvig, Как я делаю Шаблон "одиночка" в Python? (Необходимо использовать функцию поиска браузера для нахождения этого вопроса, нет никакой прямой ссылки, извините)
, Также у Bruce Eckel есть другой пример в его книге , Думающей в Python (снова нет никакой прямой ссылки на код)
Вы можете переопределить метод __ new __
следующим образом :
class Singleton(object):
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(
cls, *args, **kwargs)
return cls._instance
if __name__ == '__main__':
s1 = Singleton()
s2 = Singleton()
if (id(s1) == id(s2)):
print "Same"
else:
print "Different"
Я очень не уверен в этом, но в моем проекте используются «синглтоны соглашения» (не принудительные синглтоны), то есть, если у меня есть класс с именем DataController
, я определите это в том же модуле:
_data_controller = None
def GetDataController():
global _data_controller
if _data_controller is None:
_data_controller = DataController()
return _data_controller
Это не элегантно, так как это полные шесть строк. Но все мои синглтоны используют этот шаблон, и он, по крайней мере, очень явный (питонический).
class Singleton(object[,...]):
staticVar1 = None
staticVar2 = None
def __init__(self):
if self.__class__.staticVar1==None :
# create class instance variable for instantiation of class
# assign class instance variable values to class static variables
else:
# assign class static variable values to class instance variables
См. эту реализацию из PEP318, реализуя шаблон синглтона с декоратором:
def singleton(cls):
instances = {}
def getinstance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return getinstance
@singleton
class MyClass:
...