处理只读用户输入的面向对象方式
Object-Oriented Way of Dealing with Read-Only User Input
我正在制作一个简单的命令行游戏,但不确定如何在 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
有没有更好的方法来完成我的objective?如果有,那是什么?
供您参考,我的目标不仅仅是构建程序和 运行,而是养成良好的编程习惯。请随意复杂化并告诉我您在大型项目中更喜欢的方式(为了可扩展性和可维护性)。
.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
都是描述符。您可能需要阅读更多文档(以上 link)或检查这些项目的源代码。您可能会找到灵感 :-).
祝你好运!
我正在制作一个简单的命令行游戏,但不确定如何在 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
有没有更好的方法来完成我的objective?如果有,那是什么?
供您参考,我的目标不仅仅是构建程序和 运行,而是养成良好的编程习惯。请随意复杂化并告诉我您在大型项目中更喜欢的方式(为了可扩展性和可维护性)。
.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
都是描述符。您可能需要阅读更多文档(以上 link)或检查这些项目的源代码。您可能会找到灵感 :-).
祝你好运!