In statically typed languages to solve the problem below I would use interface (or abstract class etc.). But I wonder if in python there is more "pythonic" way of doing it.
So, consider the situation:
class MyClass(object):
# ...
def my_function(self, value_or_value_provider):
if is_value_provider(value_or_value_provider):
self._value_provider = value_or_value_provider
else:
self._value_provider = StandardValueProvider(value_or_valie_provider)
# `StandardValueProvider` just always returns the same value.
Above "value provider" is custom class, which has get_value()
method. Of course, the idea is that it can be implemented by the user.
Now, the question is: what is the best way to implement is_value_provider()
? I.e., what is the best way to distinguish between "single value" and "value provider"?
The first idea, which came to my mind is to use inheritance: Introduce base class BaseValueProvider
with empty implementation and tell in documentation, that custom "value providers" must inherit from it. Then in is_value_provider()
function just check isinstance(objectToCheck, BaseValueProvider)
. What I don't like about this solution is that inheritance seems to be somehow redundant in this case (specifically in case of python), because we cannot even force one, who derive to implement get_value()
method. Besides, for someone who wants to implement custom "value provider" this solution implies need to have a dependency on the module, which exposes BaseValueProvider
.
The other solution would be to use "trait attribute". I.e. instead of checking base class, check existence of particular attribute with hasattr()
function. We can check either existence of get_value()
method itself. Or, if we afraid, that the name of the method is too common, we could check for dedicated trait attribute, like is_my_library_value_provider
. Then in documentation tell, that any custom "value provider" must have not only get_value()
method, but also is_my_library_value_provider
. This second solution seems to be better, as it does not abuse inheritance and allows to implement custom "value providers" without being dependent on some additional library, which provides base class.
Could someone comment on which solution is preferable (or if there are other better ones), and why?
EDIT: Change the example slightly to reflect the fact, that value-provider is going to be stored and used later (probably, multiple times).