如何拒绝用户在 Python 中创建父对象的实例

Posted

技术标签:

【中文标题】如何拒绝用户在 Python 中创建父对象的实例【英文标题】:How to deny users to create an instance of a parent object in Python 【发布时间】:2013-08-17 17:51:03 【问题描述】:

假设我创建了一个名为Ball 的父类。作为子类,我将继续创建BasketballBaseballTennisbal。但是我不希望我的用户创建Ball 的实例,因为它不够具体。我想通过创建任何子类的实例来强制用户直接创建特定的球。如何拒绝访问父类并保持子类可访问?

【问题讨论】:

使用措辞强硬的文档字符串? 【参考方案1】:

基本上,你不能严格意义上。 python 中的每个类和方法都是公共的,所以这是不可能的。你可以做一些修改,但如果有人想使用它,它仍然不会停止。

按照惯例,大多数 Python 程序员都会在方法或属性前面加上 _ 来表示内部方法。但没有什么能阻止它。

一个 mangling 的例子(摘自 Python 3 Object Oriented Programming Using Python):

class SecretString:
  '''A not-at-all secure way to store a secret string.'''

    def __init__(self, plain_string, pass_phrase):
       self.__plain_string = plain_string
       self.__pass_phrase = pass_phrase

def decrypt(self, pass_phrase):
    '''Only show the string if the pass_phrase is correct.'''
      if pass_phrase == self.__pass_phrase:
     return self.__plain_string
     else:
      return ''

现在让我们试试这个:

>>> secret_string = SecretString("ACME: Top Secret", "antwerp")
>>> print(secret_string.decrypt("antwerp"))
ACME: Top Secret
>>> print(secret_string.__plain_text)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError:

哇!成功了。

现在,这个:

>>> print(secret_string._SecretString__plain_string)
ACME: Top Secret

不,它失败了。

上面是一个名称修饰的例子,你可以在最好的意义上使用它。

【讨论】:

谢谢,这很有启发性。事实上,在 Python 中,privateprotected 这样的标识符并不存在,这让我很恼火。是的,您可以在前面加上一个 _ 或两个 _,但这更像是一个警告而不是实际的拒绝。 没错,你是对的!但是 python 相信信任程序员而不是执行规则。我认为这就是python的编程哲学。如果对您有用,请随时接受答案。 好吧,我也有点相信Programmer。但是,由于ProgrammerHuman 的子类,我不会太相信Programmer 类。【参考方案2】:

让 Ball.__init__() 引发 NotImplementedError。

(编辑)

此建议的目的是保持简单。如果你需要初始化,你可以让你的基类检查所有实现者必须拥有的东西,或者只是创建一个标志来告诉你发生了什么:

class A(object):
    _abstract = True

    def __init__(self):
        if self._abstract:
            raise NotImplementedError("Cannot instantiate abstract base class")

class B(A):
    _abstract = False

【讨论】:

但是当子类调用时这不会使事情复杂化:super(Baseball, self).__init__(arg) 是的,那将是一件坏事。如果需要,您可以创建不同的初始化函数。

以上是关于如何拒绝用户在 Python 中创建父对象的实例的主要内容,如果未能解决你的问题,请参考以下文章

无法写入文件 pri:无法在 QT mac os 中创建父目录

python中创建实例属性

python - 在批量python中创建资源时如何跳过现有对象实例

设计模式之简单工厂模式

多态创建的是父类对象还是子类对象

js中创建对象方式----原型模式