Is this a good way to work with init and exception

Chris Angelico rosuav at gmail.com
Sun Jul 19 20:11:51 CEST 2015


On Mon, Jul 20, 2015 at 2:46 AM, Cecil Westerhof <Cecil at 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 <Cecil at 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


More information about the Python-list mailing list