I really hope this isn't a duplicate. I tried to search for my question and I couldn't seem to find it.
So I have a fairly simple function that converts feet to meters:
def feetToMeters(val):
return numpy.array(val) * 0.3048
This works nicely and accepts ints, floats, arrays, and lists. However, if I put in a list (instead of a numpy array), I'd like to have a list returned. So I wrote this:
def feetToMeters(val):
try:
return val * 0.3084
except TypeError:
return [0.3084 * v for v in val]
(Alternatively I could use return list(numpy.array(val) * 0.3084)
for the last line if I want to use numpy
here, which I don't know if that really matters.)
Is this the best way to incorporate duck-typing here so that I can avoid the use of the type
function? Originally I tried AttributeError
, but it didn't work. Still, I am weary about TypeError
even though it seems to work.
Would it be sacrilegious to use if type(val) is list
instead?
Duck Typing is a term commonly related to dynamically typed programming languages and polymorphism. The idea behind this principle is that the code itself does not care about whether an object is a duck, but instead it does only care about whether it quacks.
Duck typing is a concept related to dynamic typing, where the type or the class of an object is less important than the methods it defines. When you use duck typing, you do not check types at all. Instead, you check for the presence of a given method or attribute.
With duck typing you can introduce subtle bugs in your code due this lack of formal relationship. If your "quack" isn't a "quack" at all, you'll be in trouble. With inheritance, this is less likely to happen due the contractual nature of subclassing abstract classes.
advantage is that it leads to fewer lines of code. This makes it look cleaner; thus making your code easier to read and faster to write. practices, it really is useful functionality!
Would it be sacrilegious to use
if type(val) is list
instead?
Yes, because it doesn't work for subclasses of list. If you want to go this way, at least do isinstance(val, list)
. Here's a solution that treats lists specially, and convert everything else (including scalars and tuples) to NumPy arrays:
def feetToMeters(feet):
meters = np.asarray(feet) * 0.3048
return list(meters) if isinstance(feet, list) else meters
Note that:
list
will cause a plain list
to be returned;You could extend this to handle more types specially, but in general, for each type to be handled, you need to write more code as you need to know how to construct that type. Therefore, this kind of type conversion is usually left to client code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With