Is this a good way to work with init and exception
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 # Functions def init(max_tries = 5, wait_time = 60): global _core if _core != None: raise InitAlreadyDoneError tries = 0 while True: try: _core = Core() break except ServiceOverCapacity: tries += 1 sys.stderr.write('Tried to init _core it {0} times\n'.format(tries)) sys.stderr.flush() if tries = max_tries: raise time.sleep(wait_time) == Is this the correct way to work user defined exceptions, or should I also define a default message? 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? -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof -- https://mail.python.org/mailman/listinfo/python-list
Re: Is this a good way to work with init and exception
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. # 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(). (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.) tries = 0 while True: try: _core = Core() break except ServiceOverCapacity: tries += 1 sys.stderr.write('Tried to init _core it {0} times\n'.format(tries)) sys.stderr.flush() if tries = max_tries: raise time.sleep(wait_time) == 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) 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. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Is this a good way to work with init and exception
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. # 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 -- https://mail.python.org/mailman/listinfo/python-list
Re: Is this a good way to work with init and exception
On Mon, Jul 20, 2015 at 8:19 AM, Cecil Westerhof ce...@decebal.nl wrote: If two modules import the same module, they get two references to that same module, not two separate module instances. Since your parameters appear only to affect the initialization itself, this is not likely to be a problem (it's not like you'll need to authenticate with two different sets of credentials, for instance), but it will mean that the second one will import an already-initialized module. That's why I suggested the try_init function which would quietly return an immediate success if the module had already been initialized. But if this isn't going to be an issue, then your code's fine. Good to know. I would expect two different instances. I agree that in my case it would not be a problem, but I put the code on GitHub: https://github.com/CecilWesterhof/PythonLibrary/blob/master/twitterDecebal.py I should do my best to circumvent nasty surprises for users of the code. Someone else could use several Twitter accounts at the same time. Is there a way to do this? Does the instantiation of Core() involve authentication? Is it possible to call Core() more than once and use different accounts? Your send_message() takes an account identifier, so it might be you don't need separate accounts. But if, just very occasionally, you do need multiple, here's a possible design style: Have init() return the Core as well as stashing it in _core, and then have send_message() take an optional keyword argument (in 3.x, keyword-only) to choose a different core. That way, it'll by default use the most recently initialized core, but you can create multiple and manage them yourself if you so choose. (Obviously you'd use reinit_allowed=True for all the initializations.) ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Is this a good way to work with init and exception
On Sunday 19 Jul 2015 23:08 CEST, Chris Angelico wrote: On Mon, Jul 20, 2015 at 5:10 AM, Cecil Westerhof ce...@decebal.nl wrote: 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. I do not see myself doing this, but I like to know ‘everything’. When I have a program with two different modules that both import this, they would get in each-others way? How? If two modules import the same module, they get two references to that same module, not two separate module instances. Since your parameters appear only to affect the initialization itself, this is not likely to be a problem (it's not like you'll need to authenticate with two different sets of credentials, for instance), but it will mean that the second one will import an already-initialized module. That's why I suggested the try_init function which would quietly return an immediate success if the module had already been initialized. But if this isn't going to be an issue, then your code's fine. Good to know. I would expect two different instances. I agree that in my case it would not be a problem, but I put the code on GitHub: https://github.com/CecilWesterhof/PythonLibrary/blob/master/twitterDecebal.py I should do my best to circumvent nasty surprises for users of the code. Someone else could use several Twitter accounts at the same time. Is there a way to do this? -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof -- https://mail.python.org/mailman/listinfo/python-list
Re: Is this a good way to work with init and exception
On Mon, Jul 20, 2015 at 5:10 AM, Cecil Westerhof ce...@decebal.nl wrote: 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. I do not see myself doing this, but I like to know ‘everything’. When I have a program with two different modules that both import this, they would get in each-others way? How? If two modules import the same module, they get two references to that same module, not two separate module instances. Since your parameters appear only to affect the initialization itself, this is not likely to be a problem (it's not like you'll need to authenticate with two different sets of credentials, for instance), but it will mean that the second one will import an already-initialized module. That's why I suggested the try_init function which would quietly return an immediate success if the module had already been initialized. But if this isn't going to be an issue, then your code's fine. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Is this a good way to work with init and exception
On Monday 20 Jul 2015 00:40 CEST, Chris Angelico wrote: On Mon, Jul 20, 2015 at 8:19 AM, Cecil Westerhof ce...@decebal.nl wrote: If two modules import the same module, they get two references to that same module, not two separate module instances. Since your parameters appear only to affect the initialization itself, this is not likely to be a problem (it's not like you'll need to authenticate with two different sets of credentials, for instance), but it will mean that the second one will import an already-initialized module. That's why I suggested the try_init function which would quietly return an immediate success if the module had already been initialized. But if this isn't going to be an issue, then your code's fine. Good to know. I would expect two different instances. I agree that in my case it would not be a problem, but I put the code on GitHub: https://github.com/CecilWesterhof/PythonLibrary/blob/master/twitterDecebal.py I should do my best to circumvent nasty surprises for users of the code. Someone else could use several Twitter accounts at the same time. Is there a way to do this? Does the instantiation of Core() involve authentication? Is it possible to call Core() more than once and use different accounts? Your send_message() takes an account identifier, so it might be you don't need separate accounts. But if, just very occasionally, you do need multiple, here's a possible design style: Have init() return the Core as well as stashing it in _core, and then have send_message() take an optional keyword argument (in 3.x, keyword-only) to choose a different core. That way, it'll by default use the most recently initialized core, but you can create multiple and manage them yourself if you so choose. (Obviously you'd use reinit_allowed=True for all the initializations.) You are right: core is a general initialisation, so in this case nothing to worry about. :-D When I write something where it could make a difference, I should use your tip. -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof -- https://mail.python.org/mailman/listinfo/python-list
Re: Is this a good way to work with init and exception
On Sunday 19 Jul 2015 20:11 CEST, Chris Angelico wrote: 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. In my case I think the defaults are good. (But I do not know how I will use the function in the future. ;-) ) But I want to share it on GitHub and it would be possible that for someone else my defaults are not correct and then it is nice when they can be overridden. 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. I do not see myself doing this, but I like to know ‘everything’. When I have a program with two different modules that both import this, they would get in each-others way? How? -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof -- https://mail.python.org/mailman/listinfo/python-list
Re: Is this a good way to work with init and exception
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