On Mon, Jul 20, 2015 at 2:46 AM, Cecil Westerhof <ce...@decebal.nl> wrote: > On Sunday 19 Jul 2015 14:59 CEST, Chris Angelico wrote: > >> Reordering/interleaving your post to respond to different parts >> together. >> >> On Sun, Jul 19, 2015 at 8:35 PM, Cecil Westerhof <ce...@decebal.nl> wrote: >>> I am using libturpial to post things on Twitter. But sometimes I >>> get a ServiceOverCapacity exception. So I wrote the following code. >>> >>> ====================================================================== >>> class InitAlreadyDoneError(Exception): pass >> >>> Is this the correct way to work user defined exceptions, or should >>> I also define a default message? >> >> I'd start by looking through the exception hierarchy for something >> appropriate to subclass. In this case, you're basically saying "run >> init() exactly once, and if you run it a second time, I'll throw >> back an error", which probably doesn't have any logical match, so >> directly subclassing Exception would be correct. But you might >> decide that subclassing ValueError or RuntimeError is more >> appropriate. > > Subclassing ValueError or RuntimeError looks wrong to me.
Sure. Like I said, directly subclassing Exception seemed the most logical route. Just threw that out there as a possibility. >> (Side point: It might be a neat courtesy to let people call init >> again, or maybe a try_init() that won't error out if already >> initialized.) > > I changed it to: > ======================================================================== > def init(max_tries = 5, wait_time = 60, reinit_allowed = False): > global _core > > if (_core != None) and not reinit_allowed: > raise InitAlreadyDoneError > ======================================================================== That works, too! >>> I use this in the following way: >>> import twitterDecebal >>> twitterDecebal.init() >>> >>> Because you can not give parameters with an import as far as I can >>> see. Is this a good way to do this, or is there a better way? >> >> Parameterized imports aren't possible, correct. What I'd look at >> here is a more explicit instantiation. Something like: >> >> import twitterDecebal >> twitter = twitterDecebal.twitterDecebal(5, 60) > > I worked with default values, because I thought that would be a good > idea. I should remove the default values? No no, the default values are good. I just gave an example that didn't use them, as that's where you actually need the call. If you're always going to use the defaults, well, there's not a lot of point having the function. But if you often use the defaults (or one of them), and occasionally override it, then what you have is good design. >> Especially since it's something that does a ton of network >> operations and all sorts of sleeps and timeouts, I would strongly >> recommend NOT doing this on import, even if you could. If you don't >> absolutely _need_ it to be global, it'd be cleanest to make it a >> class that you construct. > > In principal I only mend that before you use the twitter functions you > need to do the init. (And because of the ton of functions I wanted a > reinit to be an error.) In my case it is exactly below the import. > Because I use it in a script and except one situation _core is always > used. So I thought it to be more clear. I think it's fine, then. As long as it makes absolutely no sense to have two separately-initialized twitter connections, and as long as it's okay for two separate modules to both import this and to then share state, then what you have is fine. ChrisA -- https://mail.python.org/mailman/listinfo/python-list