On Sat, Aug 15, 2020 at 3:36 PM Manfred Lotz <ml_n...@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. ChrisA -- https://mail.python.org/mailman/listinfo/python-list