On Sat, 15 Aug 2020 08:33:58 +0200 Peter Otten <__pete...@web.de> wrote:
> Chris Angelico wrote: > > > 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. > > > > 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 > Thanks. Also a nice method. As said in my other reply it doesn't fit to my use case. -- Manfred -- https://mail.python.org/mailman/listinfo/python-list