I'm making a simple command-line game but not sure how to model read-only user inputs in Python.
Right now, I'm thinking of declaring an ABC called Input
and subclassing it:
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
Another way I came up with is using the @property
decorator:
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
Is there a better way of accomplishing my objective? If so, what is it?
For your information, my goal is not just building a program up and running but picking up good programming habits. Please feel free to overcomplicate and tell me the way you prefer (for the sake of scalability and maintainability) in a large-scale project.
The name .pop()
is almost reserved for stacks. You shouldn't use that, as the behaviour you're doing here is different.
The @property
is pretty good, but you're misusing it. It should be:
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
The second value
function is if you want to have your value
property settable.
You can find more info there: How does the @property decorator work?
The property allows you to do some in-depth cleanup (like removing HTML injections, ...) either on input or output. I'm calling clean_data()
for the sake of the example, there.
But maybe, depending on what your actual is, you may want to create your own descriptors, so that you can reuse them. That's what happens in ORMs, for instance. More info: https://docs.python.org/3.7/howto/descriptor.html
Like, in the django ORM (eg. http://www.effectivedjango.com/orm.html ), all these models.CharField
and models.XxxXxx
are descriptors. You may want to read more documentation (link above) or checking these projects' source code. You might find inspiration :-).
Good luck!