Префиксы _
и __
не предлагают решения, ограничивающего создание экземпляра объекта определенной «фабрикой», однако Python является мощным набором инструментов, и желаемое поведение может быть достигнуто несколькими способами (как продемонстрировал @Jesse W at Z).Вот возможное решение, которое делает класс общедоступным (допускает isinstance
и т. Д.), Но гарантирует, что построение возможно только методами класса:
class OnlyCreatable(object):
__create_key = object()
@classmethod
def create(cls, value):
return OnlyCreatable(cls.__create_key, value)
def __init__(self, create_key, value):
assert(create_key == OnlyCreatable.__create_key), \
"OnlyCreatable objects must be created using OnlyCreatable.create"
self.value = value
Построение объекта с помощью метода класса create
:
>>> OnlyCreatable.create("I'm a test")
<__main__.OnlyCreatable object at 0x1023a6f60>
При попытке создать объект без использования create
создание метода класса завершается неудачно из-за утверждения:
>>> OnlyCreatable(0, "I'm a test")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 11, in __init__
AssertionError: OnlyCreatable objects can only be created using OnlyCreatable.create
При попытке создать объект путем имитацииcreate
Создание метода класса завершается неудачно из-за искажения компилятором OnlyCreatable.__createKey
.
>>> OnlyCreatable(OnlyCreatable.__createKey, "I'm a test")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'OnlyCreatable' has no attribute '__createKey'
Единственный способ создать OnlyCreatable
вне метода класса - это узнать значение OnlyCreatable.__create_key
.Поскольку значение этого атрибута класса генерируется во время выполнения, а его имя имеет префикс __, помечающий его как недоступный, фактически «невозможно» получить это значение и / или построить объект.