Path: csiph.com!usenet.pasdenom.info!news.redatomik.org!newsfeed.xs4all.nl!newsfeed7.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'defaults': 0.05; 'used.': 0.05; 'correct.': 0.07; 'exception.': 0.07; 'none)': 0.07; 'override': 0.07; 'see.': 0.07; 'seemed': 0.07; 'cc:addr:python- list': 0.09; '"run': 0.09; 'appropriate.': 0.09; 'exceptions,': 0.09; 'global,': 0.09; 'imports': 0.09; 'okay': 0.09; 'throw': 0.09; 'valueerror': 0.09; 'way:': 0.09; 'skip:= 70': 0.10; 'exception': 0.13; 'def': 0.13; 'appropriate': 0.14; '60,': 0.16; 'clear.': 0.16; 'construct.': 0.16; 'defaults,': 0.16; 'false):': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris angelico': 0.16; 'hierarchy': 0.16; 'runtimeerror': 0.16; 'sorts': 0.16; 'subclassing': 0.16; 'subject:exception': 0.16; 'sure.': 0.16; 'threw': 0.16; 'wrote:': 0.16; 'basically': 0.18; '>>>': 0.20; 'together.': 0.20; '2015': 0.20; 'cc:2**0': 0.20; 'cc:addr:python.org': 0.20; 'saying': 0.22; "aren't": 0.22; 'explicit': 0.22; 'fine,': 0.22; 'init': 0.22; 'logical': 0.22; 'pass': 0.22; 'am,': 0.23; 'code.': 0.23; 'decide': 0.23; 'defined': 0.23; '(or': 0.23; 'wrote': 0.23; 'second': 0.24; 'import': 0.24; 'header:In-Reply-To:1': 0.24; 'mon,': 0.24; 'script': 0.25; "doesn't": 0.26; 'example': 0.26; 'sense': 0.26; 'chris': 0.26; 'error': 0.27; 'define': 0.27; 'parameters': 0.27; 'separate': 0.27; 'message-id:@mail.gmail.com': 0.27; 'said,': 0.27; 'then.': 0.27; 'correct': 0.28; 'values': 0.28; 'looks': 0.29; 'occasionally': 0.29; 'once,': 0.29; 'way?': 0.29; 'raise': 0.29; 'call.': 0.30; 'strongly': 0.30; "i'd": 0.31; 'operations': 0.31; 'probably': 0.31; 'post': 0.31; 'especially': 0.32; 'good.': 0.32; 'maybe': 0.33; 'run': 0.33; 'point': 0.33; 'changed': 0.33; 'class': 0.33; "i'll": 0.33; 'case,': 0.34; 'except': 0.34; 'worked': 0.34; 'received:google.com': 0.35; 'possible,': 0.35; 'something': 0.35; 'sometimes': 0.35; 'but': 0.36; 'skip:i 20': 0.36; 'should': 0.36; 'there': 0.36; '(and': 0.36; 'modules': 0.36; 'subject:work': 0.36; 'pm,': 0.36; 'subject:: ': 0.37; 'two': 0.37; 'thought': 0.37; 'wanted': 0.37; 'things': 0.38; 'doing': 0.38; 'no,': 0.38; "won't": 0.38; 'wrong': 0.38; 'does': 0.39; "didn't": 0.39; 'where': 0.40; 'subject:with': 0.40; 'your': 0.60; 'share': 0.61; 'default': 0.61; 'back': 0.62; 'more': 0.63; 'different': 0.63; '20,': 0.66; 'state,': 0.66; 'here': 0.66; 'situation': 0.67; 'design.': 0.72; 'jul': 0.72; 'sunday': 0.72; 'cecil': 0.84; 'chrisa': 0.84; "it'd": 0.84; 'subject:good': 0.84; 'westerhof': 0.84; 'subject:this': 0.85; 'absolutely': 0.88; 'to:none': 0.91 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:cc :content-type; bh=kKxEDs4TXFi2tFYRo4fPPTIYv9Me49MosCRlSs9H6p0=; b=hYIoxPzVbZuFKHG5H/viHuni9iexskx2YZajh26woCm8CyOpKeBIt2iA6WCsNhLEMN GWuLoZ9L1DX1mWnZeOEJtlqL5nTs/Oa+TMmRpalbci8gBIQaSOMLI8YBThInTOStqtCO fTyW7bzkUyOvCpva1rnOFJ1NpuAdejNhLdWyWGdWmTgjWg/ATUeg+3MvXHn5/1vUpsw4 XI994fX1x6o6+KsmDLvZmHcWeHn1DKmg1dwwqWJK0+oK1VClJ55dM9k/ew4dV8dBw/bo PzfL+lHBedFVM1hQjUyiGIlNYuy2iQ/5tq70RSxzOSdFBtE0TrAuEtUjwllhYQqJzfNL /f5w== MIME-Version: 1.0 X-Received: by 10.107.4.1 with SMTP id 1mr28394925ioe.10.1437329511941; Sun, 19 Jul 2015 11:11:51 -0700 (PDT) In-Reply-To: <87r3o4xfhx.fsf@Equus.decebal.nl> References: <87380kzb8b.fsf@Equus.decebal.nl> <87r3o4xfhx.fsf@Equus.decebal.nl> Date: Mon, 20 Jul 2015 04:11:51 +1000 Subject: Re: Is this a good way to work with init and exception From: Chris Angelico Cc: "python-list@python.org" Content-Type: text/plain; charset=UTF-8 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.20+ Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 84 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1437329515 news.xs4all.nl 2879 [2001:888:2000:d::a6]:55128 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:94144 On Mon, Jul 20, 2015 at 2:46 AM, Cecil Westerhof 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 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