_ 和 __ 前缀没有提供将对象实例化限制为特定“工厂”的解决方案,但是 Python 是一个强大的工具箱,并且可以通过多种方式实现所需的行为(正如 Z 的@Jesse W 所证明的那样)。
这是一个可能的解决方案,可以让类公开可见(允许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 的值。由于此类属性的值是在运行时生成的,并且它的名称以 __ 为前缀,将其标记为不可访问,因此实际上“不可能”获取该值和/或构造对象。