我正在制作一个简单的命令行游戏,但不确定如何在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
有没有更好的方法可以实现我的目标?如果是这样,那是什么?
为您提供信息,我的目标不仅是建立并运行程序,而且还要养成良好的编程习惯。请不要过于复杂,并告诉我您在大型项目中的首选方式(出于可伸缩性和可维护性)。
答案 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.CharField
和models.XxxXxx
都是描述符。您可能需要阅读更多文档(上面的链接)或查看这些项目的源代码。您可能会发现灵感:-)。
祝你好运!