Is this a good way to work with init and exception

Cecil Westerhof Cecil at decebal.nl
Sun Jul 19 18:46:02 CEST 2015


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.


>> ##### Functions
>> def init(max_tries = 5, wait_time = 60):
>> global _core
>>
>> if _core != None:
>> raise InitAlreadyDoneError
>
> This is where I'd add a message, if you want one. But it looks to me
> as if there's never going to be any other place that raises this, so
> the message would be redundant. InitAlreadyDoneError implies "you
> called init() after someone else called init()".

I thought so, but just wanted to be sure. ;-)


> (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
========================================================================

>> 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?


> 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.

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof


More information about the Python-list mailing list