[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Coding technique: distinguish using type or abc?

Do you prefer to use isinstance() with type() or to refer to

This team producing bases statistical analyses for (lesser capable) 
user-coders to utilise with their own experimental 'control code'; faces 
situations where a list-parameter is often only one element long. As is 
so often the way, amongst the 'clients' there are a couple of 
strong-minded (am not allowed to call them "awkward", or otherwise!) 
user-coder-analysts, who demand that entry of a single-element not 
require them to surround it with "unnecessary" square-brackets. Despite 
complaining, we realise that this is actually quite a good practice, and 
likely save us (as well as 'them') from interface mistakes.

Such single elements appear in both string and numeric formats, but for 
simplicity (here) let's ignore numerics...

The problem rearing its ugly head, is when the string single-element 
becomes input to a for-loop. If we loop around a list, then each element 
is handled individually (as desired). Whereas if the element is a 
string, then each character is treated as if it were a list-element (not)!

In Code Review, I noticed that two 'solutions' have been coded.

1 using type()s to distinguish:

	def format_as_list( parameter:Union[ str, list ] )->list:
		if isinstance( parameter, str ):
			parameter_list = [ parameter ]
		elif isinstance( parameter, list ):
			parameter_list = parameter
			raise NotImplementedError
		return parameter_list
2 using abstract base classes from PSL.collections to distinguish:

	import as abc
	def is_list_not_string( parameter:Union[ str, list ] ) -> bool:
		return isinstance( parameter, abc.MutableSequence )

	def format_as_list( parameter:str )->list:
		if is_list_not_string( parameter ):
			return parameter
			return [ parameter, ]
(ignoring implicit assumption/error!)
NB I've simplified the code and attempted to harmonise the varNMs 
between snippets.

With our preference for EAFP, I went looking for a way to utilise an 
exception by way of distinguishing between the input-types - but 
couldn't see how, without major artifice (false/purposeless construct 
which would confuse the next reader of the code). That said, I'm 
wondering if using (or appearing to use) tuples and *args might solve 
the problem - but will have to dig back through the code-base...

Meantime, faced with such a challenge, would you recommend utilising one 
of these ideas over the other, or perhaps some other solution?

Are there perhaps circumstances where you would use one solution, and 
others the other?