try..except or type() or isinstance()?
Peter Otten
__peter__ at web.de
Sat Aug 15 02:33:58 EDT 2020
Chris Angelico wrote:
> On Sat, Aug 15, 2020 at 3:36 PM Manfred Lotz <ml_news at posteo.de> wrote:
>>
>> I have an object which I could initialize providind an int or a str.
>>
>> I am not sure which of the following is best to use
>> - try/except
>> - if type(int)...
>> - if isinstance(v, int)
>>
>> Here a minimal example
>>
>> def get_id(fromname):
>> # do something with `fromname`
>> return 0
>>
>> def get_name(fromid):
>> # do something with `fromid`
>> return "something"
>>
>> """ For O1, O2, O3: self.myid is int
>> self.name is str
>> """
>> class O1:
>> def __init__(self, val):
>> try:
>> self.myid = int(val)
>> self.name = get_name(self.myid)
>> except:
>> self.myid = get_id(val)
>> self.name = val
>
> Don't use a bare "except" - use "except ValueError" instead. But
> otherwise, this is a perfectly reasonable way to say "anything that
> can be interpreted as an integer will be".
>
>> class O2:
>> def __init__(self, val):
>> if type(val) == int:
>> self.myid = val
>> self.name = get_name(self.myid)
>> else:
>> self.myid = get_id(val)
>> self.name = val
>
> Nope, don't do this. It's strictly worse than O3.
>
>> class O3:
>> def __init__(self, val):
>> if isinstance(val, int):
>> self.myid = val
>> self.name = get_name(self.myid)
>> else:
>> self.myid = get_id(val)
>> self.name = val
>
> This is a perfectly reasonable way to say "integers will be treated as
> IDs". Note that O1 and O3 are very different semantically; O1 will
> treat the string "7" as an ID, but O3 will treat it as a name.
>
> Here's an even better way:
>
> class O4:
> def __init__(self, id):
> self.myid = id
> self.name = get_name(id)
> @classmethod
> def from_name(cls, name):
> return cls(get_id(name))
>
> This makes the ID the main way you'd do things, and a name lookup as
> an alternate constructor. Very good pattern, reliable, easy to use.
Yet another way: keyword arguments:
class O5:
def __init__(self, *, id=None, name=None):
if name is None:
assert id is not None
name = get_name(id)
else:
assert id is None
id = get_id(name)
self.id = id
self.name = name
More information about the Python-list
mailing list