只读用户输入的面向对象方式

时间:2018-11-23 08:54:19

标签: python oop input modeling

我正在制作一个简单的命令行游戏,但不确定如何在Python中为只读用户输入建模。

现在,我正在考虑声明一个名为Input的ABC并将其子类化:

import abc


class Input(abc.ABC):
    @abc.abstractmethod
    def is_valid(self, *args, **kwargs):
        pass

    @abc.abstractmethod
    def pop(self):
        pass


class NameInput(Input):
    def __init__(self, name):
        self._name = name

    def is_valid(self, *args, **kwargs):
        pass

    def pop(self):
        return self._name

我想到的另一种方法是使用@property装饰器:

import abc


class Input(abc.ABC):
    @abc.abstractmethod
    def is_valid(self, *args, **kwargs):
        pass

    @abc.abstractmethod
    def value(self, value, *args, **kwargs):
        pass


class NameInput(Input):
    def __init__(self, name):
        self._name = name

    def is_valid(self, *args, **kwargs):
        pass

    @property
    def value(self, value, *args, **kwargs):
        return self._name

有没有更好的方法可以实现我的目标?如果是这样,那是什么?

为您提供信息,我的目标不仅是建立并运行程序,而且还要养成良好的编程习惯。请不要过于复杂,并告诉我您在大型项目中的首选方式(出于可伸缩性和可维护性)。

1 个答案:

答案 0 :(得分:0)

名称.pop()几乎是为堆栈保留的。您不应该使用它,因为您在这里所做的行为是不同的。

@property很好,但是您滥用它。应该是:

class NameInput(Input):
    def __init__(self, name):
        self._name = name

    def is_valid(self, *args, **kwargs):
        pass

    @property
    def value(self):
        return clean_data(self._name)

    @value.setter
    def value(self, value):
        self._name = value

第二个value函数是要设置value属性的情况。

您可以在此处找到更多信息:How does the @property decorator work?

该属性允许您对输入或输出进行一些深入的清理(如删除HTML注入,...)。出于示例的原因,我在这里叫clean_data()

但是,也许,根据实际情况,您可能想要创建自己的描述符,以便您可以重用它们。例如,这就是ORM中发生的情况。更多信息:https://docs.python.org/3.7/howto/descriptor.html

就像在django ORM(例如http://www.effectivedjango.com/orm.html)中,所有这些models.CharFieldmodels.XxxXxx都是描述符。您可能需要阅读更多文档(上面的链接)或查看这些项目的源代码。您可能会发现灵感:-)。

祝你好运!