Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #49801 > unrolled thread
| Started by | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| First post | 2013-07-04 03:27 +0000 |
| Last post | 2013-07-08 17:58 +0100 |
| Articles | 20 on this page of 60 — 13 participants |
Back to article view | Back to comp.lang.python
Default scope of variables Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-07-04 03:27 +0000
Re: Default scope of variables Chris Angelico <rosuav@gmail.com> - 2013-07-04 14:07 +1000
Re: Default scope of variables Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-07-04 05:32 +0000
Re: Default scope of variables Chris Angelico <rosuav@gmail.com> - 2013-07-04 15:47 +1000
Re: Default scope of variables Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-07-04 16:38 +0000
Re: Default scope of variables Chris Angelico <rosuav@gmail.com> - 2013-07-05 02:58 +1000
Re: Default scope of variables Wayne Werner <wayne@waynewerner.com> - 2013-07-07 08:13 -0500
Re: Default scope of variables Chris Angelico <rosuav@gmail.com> - 2013-07-07 23:43 +1000
Re: Default scope of variables Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-07-07 16:03 +0000
Re: Default scope of variables Chris Angelico <rosuav@gmail.com> - 2013-07-08 10:46 +1000
Re: Default scope of variables alex23 <wuwei23@gmail.com> - 2013-07-09 14:52 +1000
Re: Default scope of variables Chris Angelico <rosuav@gmail.com> - 2013-07-09 15:07 +1000
Re: Default scope of variables alex23 <wuwei23@gmail.com> - 2013-07-09 16:08 +1000
Re: Default scope of variables Chris Angelico <rosuav@gmail.com> - 2013-07-09 16:13 +1000
Re: Default scope of variables "Frank Millman" <frank@chagford.com> - 2013-07-09 09:35 +0200
Re: Default scope of variables Chris Angelico <rosuav@gmail.com> - 2013-07-09 17:45 +1000
Re: Default scope of variables Ian Kelly <ian.g.kelly@gmail.com> - 2013-07-09 01:56 -0600
Re: Default scope of variables "Frank Millman" <frank@chagford.com> - 2013-07-09 10:22 +0200
Re: Default scope of variables "Frank Millman" <frank@chagford.com> - 2013-07-09 10:38 +0200
Re: Default scope of variables Ethan Furman <ethan@stoneleaf.us> - 2013-07-09 09:07 -0700
Re: Default scope of variables Ian Kelly <ian.g.kelly@gmail.com> - 2013-07-09 10:44 -0600
Re: Default scope of variables Ethan Furman <ethan@stoneleaf.us> - 2013-07-09 10:23 -0700
Re: Default scope of variables Ian Kelly <ian.g.kelly@gmail.com> - 2013-07-09 12:41 -0600
Re: Default scope of variables Ethan Furman <ethan@stoneleaf.us> - 2013-07-09 12:19 -0700
Re: Default scope of variables "Frank Millman" <frank@chagford.com> - 2013-07-10 07:54 +0200
Re: Default scope of variables Ian Kelly <ian.g.kelly@gmail.com> - 2013-07-10 09:42 -0600
Re: Default scope of variables Ethan Furman <ethan@stoneleaf.us> - 2013-07-10 08:29 -0700
Re: Default scope of variables "Frank Millman" <frank@chagford.com> - 2013-07-11 07:52 +0200
Re: Default scope of variables Ethan Furman <ethan@stoneleaf.us> - 2013-07-07 09:52 -0700
Re: Default scope of variables Ethan Furman <ethan@stoneleaf.us> - 2013-07-07 11:59 -0700
Re: Default scope of variables Chris Angelico <rosuav@gmail.com> - 2013-07-08 10:48 +1000
Re: Default scope of variables Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-07-08 02:23 +0000
Re: Default scope of variables Chris Angelico <rosuav@gmail.com> - 2013-07-08 13:11 +1000
Re: Default scope of variables Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-07-08 05:00 +0000
Re: Default scope of variables Chris Angelico <rosuav@gmail.com> - 2013-07-08 15:14 +1000
Re: Default scope of variables Peter Otten <__peter__@web.de> - 2013-07-04 08:48 +0200
Re: Default scope of variables Ian Kelly <ian.g.kelly@gmail.com> - 2013-07-04 01:12 -0600
Re: Default scope of variables Dave Angel <davea@davea.name> - 2013-07-04 03:06 -0400
Re: Default scope of variables Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-07-04 15:52 +0000
Re: Default scope of variables Rotwang <sg552@hotmail.co.uk> - 2013-07-04 17:54 +0100
Re: Default scope of variables Peter Otten <__peter__@web.de> - 2013-07-04 20:36 +0200
Re: Default scope of variables Joshua Landau <joshua.landau.ws@gmail.com> - 2013-07-05 01:04 +0100
Re: Default scope of variables Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-07-05 01:24 +0000
Re: Default scope of variables Dave Angel <davea@davea.name> - 2013-07-04 22:03 -0400
Re: Default scope of variables Joshua Landau <joshua.landau.ws@gmail.com> - 2013-07-05 03:29 +0100
Re: Default scope of variables Joshua Landau <joshua.landau.ws@gmail.com> - 2013-07-05 03:27 +0100
Re: Default scope of variables Rotwang <sg552@hotmail.co.uk> - 2013-07-05 07:28 +0100
Re: Default scope of variables Neil Cerutti <neilc@norwich.edu> - 2013-07-05 13:24 +0000
Re: Default scope of variables Chris Angelico <rosuav@gmail.com> - 2013-07-05 23:43 +1000
Re: Default scope of variables Neil Cerutti <neilc@norwich.edu> - 2013-07-05 15:36 +0000
Re: Default scope of variables Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-07-07 16:08 +0000
Re: Default scope of variables Neil Cerutti <neilc@norwich.edu> - 2013-07-08 11:54 +0000
Re: Default scope of variables Joshua Landau <joshua.landau.ws@gmail.com> - 2013-07-08 14:14 +0100
Re: Default scope of variables Lele Gaifax <lele@metapensiero.it> - 2013-07-04 14:43 +0200
Re: Default scope of variables Wayne Werner <wayne@waynewerner.com> - 2013-07-04 10:45 -0500
Re: Default scope of variables Joshua Landau <joshua.landau.ws@gmail.com> - 2013-07-04 05:30 +0100
Re: Default scope of variables Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-07-04 05:45 +0000
Re: Default scope of variables Chris Angelico <rosuav@gmail.com> - 2013-07-04 14:36 +1000
Re: Default scope of variables Joshua Landau <joshua.landau.ws@gmail.com> - 2013-07-04 06:09 +0100
Re: Default scope of variables Joshua Landau <joshua.landau.ws@gmail.com> - 2013-07-08 17:58 +0100
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2013-07-09 10:44 -0600 |
| Message-ID | <mailman.4462.1373388305.3114.python-list@python.org> |
| In reply to | #50209 |
On Tue, Jul 9, 2013 at 10:07 AM, Ethan Furman <ethan@stoneleaf.us> wrote: > You could also do it like this: > > def updating(self): > self.transaction_active = True > return self Yes, that would be simpler. I was all set to point out why this doesn't work, and then I noticed that the location of the "transaction_active" attribute is not consistent in the original code. The DbSession class places it on self, and then the example usage places it on the connection object (which I had based my version on). Since that seems to be a source of confusion, it demonstrates another reason why factoring this out is a good thing.
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2013-07-09 10:23 -0700 |
| Message-ID | <mailman.4466.1373392017.3114.python-list@python.org> |
| In reply to | #50209 |
On 07/09/2013 09:44 AM, Ian Kelly wrote: > On Tue, Jul 9, 2013 at 10:07 AM, Ethan Furman <ethan@stoneleaf.us> wrote: >> You could also do it like this: >> >> def updating(self): >> self.transaction_active = True >> return self > > Yes, that would be simpler. I was all set to point out why this > doesn't work, and then I noticed that the location of the > "transaction_active" attribute is not consistent in the original code. > The DbSession class places it on self, and then the example usage > places it on the connection object It looks like DbSession has a conn object, and in the example he has DbSession() named as conn -- ironic, considering this is a variable scoping thread. ;) -- ~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2013-07-09 12:41 -0600 |
| Message-ID | <mailman.4467.1373395321.3114.python-list@python.org> |
| In reply to | #50209 |
On Tue, Jul 9, 2013 at 11:23 AM, Ethan Furman <ethan@stoneleaf.us> wrote: > On 07/09/2013 09:44 AM, Ian Kelly wrote: >> >> On Tue, Jul 9, 2013 at 10:07 AM, Ethan Furman <ethan@stoneleaf.us> wrote: >>> >>> You could also do it like this: >>> >>> def updating(self): >>> self.transaction_active = True >>> return self >> >> >> Yes, that would be simpler. I was all set to point out why this >> doesn't work, and then I noticed that the location of the >> "transaction_active" attribute is not consistent in the original code. >> The DbSession class places it on self, and then the example usage >> places it on the connection object > > > It looks like DbSession has a conn object, and in the example he has > DbSession() named as conn -- ironic, considering this is a variable scoping > thread. ;) The object returned by __enter__ is the conn object, not the DbSession, so naming it "conn" is correct.
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2013-07-09 12:19 -0700 |
| Message-ID | <mailman.4469.1373399640.3114.python-list@python.org> |
| In reply to | #50209 |
On 07/09/2013 11:41 AM, Ian Kelly wrote: > On Tue, Jul 9, 2013 at 11:23 AM, Ethan Furman <ethan@stoneleaf.us> wrote: >> On 07/09/2013 09:44 AM, Ian Kelly wrote: >>> >>> On Tue, Jul 9, 2013 at 10:07 AM, Ethan Furman <ethan@stoneleaf.us> wrote: >>>> >>>> You could also do it like this: >>>> >>>> def updating(self): >>>> self.transaction_active = True >>>> return self >>> >>> >>> Yes, that would be simpler. I was all set to point out why this >>> doesn't work, and then I noticed that the location of the >>> "transaction_active" attribute is not consistent in the original code. >>> The DbSession class places it on self, and then the example usage >>> places it on the connection object >> >> >> It looks like DbSession has a conn object, and in the example he has >> DbSession() named as conn -- ironic, considering this is a variable scoping >> thread. ;) > > The object returned by __enter__ is the conn object, not the > DbSession, so naming it "conn" is correct. Huh. I didn't realize a different object could be returned by __enter__ without affecting which object's __exit__ gets called. Thanks for the lesson! :) -- ~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | "Frank Millman" <frank@chagford.com> |
|---|---|
| Date | 2013-07-10 07:54 +0200 |
| Message-ID | <mailman.4486.1373435673.3114.python-list@python.org> |
| In reply to | #50209 |
"Ian Kelly" <ian.g.kelly@gmail.com> wrote in message
news:CALwzidnf3Obe0eNf3xTHLj5a40K8HxVThVEipECQ8+34ZxyLxw@mail.gmail.com...
> On Tue, Jul 9, 2013 at 10:07 AM, Ethan Furman <ethan@stoneleaf.us> wrote:
>> You could also do it like this:
>>
>> def updating(self):
>> self.transaction_active = True
>> return self
>
> Yes, that would be simpler. I was all set to point out why this
> doesn't work, and then I noticed that the location of the
> "transaction_active" attribute is not consistent in the original code.
> The DbSession class places it on self, and then the example usage
> places it on the connection object (which I had based my version on).
> Since that seems to be a source of confusion, it demonstrates another
> reason why factoring this out is a good thing.
You had me worried there for a moment, as that is obviously an error.
Then I checked my actual code, and I find that I mis-transcribed it. It
actually looks like this -
with db_session as conn:
db_session.transaction_active = True
conn.cur.execute(...)
I am still not quite sure what your objection is to this. It feels
straightforward to me.
Here is one possible answer. Whenever I want to commit a transaction I have
to add the extra line. There is a danger that I could mis-spell
'transaction_active', in which case it would not raise an error, but would
not commit the transaction, which could be a hard-to-trace bug. Using your
approach, if I mis-spelled 'db_session.connect()', it would immediately
raise an error.
Is that your concern, or are there other issues?
Frank
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2013-07-10 09:42 -0600 |
| Message-ID | <mailman.4526.1373470972.3114.python-list@python.org> |
| In reply to | #50209 |
On Tue, Jul 9, 2013 at 11:54 PM, Frank Millman <frank@chagford.com> wrote: > You had me worried there for a moment, as that is obviously an error. > > Then I checked my actual code, and I find that I mis-transcribed it. It > actually looks like this - > > with db_session as conn: > db_session.transaction_active = True > conn.cur.execute(...) > > I am still not quite sure what your objection is to this. It feels > straightforward to me. > > Here is one possible answer. Whenever I want to commit a transaction I have > to add the extra line. There is a danger that I could mis-spell > 'transaction_active', in which case it would not raise an error, but would > not commit the transaction, which could be a hard-to-trace bug. Using your > approach, if I mis-spelled 'db_session.connect()', it would immediately > raise an error. > > Is that your concern, or are there other issues? Yes, that is one concern. Another is that since you mistakenly typed "conn" instead of "db_session" once, you might make the same mistake again in actual code, with the same effect (unless the conn object doesn't allow arbitrary attributes, which is a possibility). Another is that the code adheres better to the DRY principle if you don't need to copy that line all over the place.
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2013-07-10 08:29 -0700 |
| Message-ID | <mailman.4529.1373471632.3114.python-list@python.org> |
| In reply to | #50209 |
On 07/09/2013 10:54 PM, Frank Millman wrote: > > "Ian Kelly" <ian.g.kelly@gmail.com> wrote in message > news:CALwzidnf3Obe0eNf3xTHLj5a40K8HxVThVEipECQ8+34ZxyLxw@mail.gmail.com... >> On Tue, Jul 9, 2013 at 10:07 AM, Ethan Furman <ethan@stoneleaf.us> wrote: >>> You could also do it like this: >>> >>> def updating(self): >>> self.transaction_active = True >>> return self >> >> Yes, that would be simpler. I was all set to point out why this >> doesn't work, and then I noticed that the location of the >> "transaction_active" attribute is not consistent in the original code. >> The DbSession class places it on self, and then the example usage >> places it on the connection object (which I had based my version on). >> Since that seems to be a source of confusion, it demonstrates another >> reason why factoring this out is a good thing. > > You had me worried there for a moment, as that is obviously an error. > > Then I checked my actual code, and I find that I mis-transcribed it. It > actually looks like this - > > with db_session as conn: > db_session.transaction_active = True > conn.cur.execute(...) > > I am still not quite sure what your objection is to this. It feels > straightforward to me. > > Here is one possible answer. Whenever I want to commit a transaction I have > to add the extra line. There is a danger that I could mis-spell > 'transaction_active', in which case it would not raise an error, but would > not commit the transaction, which could be a hard-to-trace bug. Using your > approach, if I mis-spelled 'db_session.connect()', it would immediately > raise an error. > > Is that your concern, or are there other issues? That concern is big enough. I've been bitten by that type of thing enough in my own code to want to avoid it where possible. Plus the `with db_session.updating() as conn:` saves keystrokes. ;) -- ~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | "Frank Millman" <frank@chagford.com> |
|---|---|
| Date | 2013-07-11 07:52 +0200 |
| Message-ID | <mailman.4567.1373522000.3114.python-list@python.org> |
| In reply to | #50209 |
"Ian Kelly" <ian.g.kelly@gmail.com> wrote in message news:CALwzidk2+b5bYM5B+XVtoZ8LHeyVHcos4v58F8Z2o1Jb6sAzog@mail.gmail.com... > On Tue, Jul 9, 2013 at 11:54 PM, Frank Millman <frank@chagford.com> wrote: >> You had me worried there for a moment, as that is obviously an error. >> >> Then I checked my actual code, and I find that I mis-transcribed it. It >> actually looks like this - >> >> with db_session as conn: >> db_session.transaction_active = True >> conn.cur.execute(...) >> >> I am still not quite sure what your objection is to this. It feels >> straightforward to me. >> >> Here is one possible answer. Whenever I want to commit a transaction I >> have >> to add the extra line. There is a danger that I could mis-spell >> 'transaction_active', in which case it would not raise an error, but >> would >> not commit the transaction, which could be a hard-to-trace bug. Using >> your >> approach, if I mis-spelled 'db_session.connect()', it would immediately >> raise an error. >> >> Is that your concern, or are there other issues? > > Yes, that is one concern. Another is that since you mistakenly typed > "conn" instead of "db_session" once, you might make the same mistake > again in actual code, with the same effect (unless the conn object > doesn't allow arbitrary attributes, which is a possibility). Another > is that the code adheres better to the DRY principle if you don't need > to copy that line all over the place. Thanks to you and Ethan - that does make sense. I have reviewed my code base to see how many occurrences there are, and there are just three. All database objects inherit from a DbOject class. The class has a save() method and a delete() method. Each of these requires a commit, so I use my technique there. All database updates are activated by calling save() or delete(). I have an init.py script to 'bootstrap' a brand new installation, which requires populating an empty database with some basic structures up front. DbObject cannot be used here as the required plumbing is not in place, so I use my technique here as well. However, this does not invalidate your general point, so I will keep it in mind. Thanks Frank
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2013-07-07 09:52 -0700 |
| Message-ID | <mailman.4358.1373217388.3114.python-list@python.org> |
| In reply to | #49885 |
On 07/07/2013 06:43 AM, Chris Angelico wrote:
> On Sun, Jul 7, 2013 at 11:13 PM, Wayne Werner <wayne@waynewerner.com> wrote:
>> Which you would then use like:
>>
>>
>> conn = create_conn()
>> with new_transaction(conn) as tran:
>> rows_affected = do_query_stuff(tran)
>> if rows_affected == 42:
>> tran.commit()
>
> Yep. There's a problem, though, when you bring in subtransactions. The
> logic wants to be like this:
Is there some reason you can't simply do this?
with new_transaction(conn) as tran1:
tran1.query("blah")
with tran1.subtransaction() as tran2:
tran2.query("blah")
with tran2.subtransaction() as tran3:
tran3.query("blah")
# roll this subtransaction back
tran2.query("blah")
tran2.commit()
tran1.query("blah")
tran1.commit()
--
~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2013-07-07 11:59 -0700 |
| Message-ID | <mailman.4359.1373224898.3114.python-list@python.org> |
| In reply to | #49885 |
On 07/07/2013 06:43 AM, Chris Angelico wrote:
>
> The 'with' statement doesn't allow this. I would need to use some kind
> of magic to rebind the old transaction to the name, or else use a list
> that gets magically populated:
>
> with new_transaction(conn) as tran:
> tran[-1].query("blah")
> with subtransaction(tran):
> tran[-1].query("blah")
> with subtransaction(tran):
> tran[-1].query("blah")
> # roll this subtransaction back
> tran[-1].query("blah")
> tran[-1].commit()
> tran[-1].query("blah")
> tran[-1].commit()
The other option is to build the magic into the new_transaction class, then your code will look like:
with new_transaction(conn) as tran:
tran.query("blah")
with tran.subtransaction():
tran.query("blah")
with tran.subtransaction():
tran.query("blah")
# roll this subtransaction back
tran.query("blah")
tran.commit()
tran.query("blah")
tran.commit()
This would definitely make more sense in a loop. ;)
--
~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2013-07-08 10:48 +1000 |
| Message-ID | <mailman.4361.1373244492.3114.python-list@python.org> |
| In reply to | #49885 |
On Mon, Jul 8, 2013 at 2:52 AM, Ethan Furman <ethan@stoneleaf.us> wrote:
> On 07/07/2013 06:43 AM, Chris Angelico wrote:
>>
>> On Sun, Jul 7, 2013 at 11:13 PM, Wayne Werner <wayne@waynewerner.com>
>> wrote:
>>>
>>> Which you would then use like:
>>>
>>>
>>> conn = create_conn()
>>> with new_transaction(conn) as tran:
>>> rows_affected = do_query_stuff(tran)
>>> if rows_affected == 42:
>>> tran.commit()
>>
>>
>> Yep. There's a problem, though, when you bring in subtransactions. The
>> logic wants to be like this:
>
>
> Is there some reason you can't simply do this?
>
> with new_transaction(conn) as tran1:
> tran1.query("blah")
> with tran1.subtransaction() as tran2:
> tran2.query("blah")
> with tran2.subtransaction() as tran3:
> tran3.query("blah")
>
> # roll this subtransaction back
> tran2.query("blah")
> tran2.commit()
> tran1.query("blah")
> tran1.commit()
That means that I, as programmer, have to keep track of the nesting
level of subtransactions. Extremely ugly. A line of code can't be
moved around without first checking which transaction object to work
with.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-07-08 02:23 +0000 |
| Message-ID | <51da2294$0$6512$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #50112 |
On Mon, 08 Jul 2013 10:48:03 +1000, Chris Angelico wrote: [...] > That means that I, as programmer, have to keep track of the nesting > level of subtransactions. Extremely ugly. A line of code can't be moved > around without first checking which transaction object to work with. I feel your pain, but I wonder why we sometimes accept "a line of code can't be moved around" as an issue to be solved by the language. After all, in general most lines of code can't be moved around. -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2013-07-08 13:11 +1000 |
| Message-ID | <mailman.4363.1373253106.3114.python-list@python.org> |
| In reply to | #50114 |
On Mon, Jul 8, 2013 at 12:23 PM, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: > On Mon, 08 Jul 2013 10:48:03 +1000, Chris Angelico wrote: > [...] >> That means that I, as programmer, have to keep track of the nesting >> level of subtransactions. Extremely ugly. A line of code can't be moved >> around without first checking which transaction object to work with. > > I feel your pain, but I wonder why we sometimes accept "a line of code > can't be moved around" as an issue to be solved by the language. After > all, in general most lines of code can't be moved around. It's not something to be solved by the language, but it's often something to be solved by the program's design. Two lines of code that achieve the same goal should normally look the same. This is why Python's policy is "one obvious way to do something" rather than "spell it five different ways in the same file to make a nightmare for other people coming after you". Why should database queries be spelled "trans1.query()" in one place, and "trans2.query()" in another? Similarly, if I want to call another function and that function needs to use the database, why should I pass it trans3 and have that come out as trans1 on the other side? Unnecessarily confusing. Makes much more sense to use the same name everywhere. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-07-08 05:00 +0000 |
| Message-ID | <51da4780$0$6512$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #50115 |
On Mon, 08 Jul 2013 13:11:37 +1000, Chris Angelico wrote: > On Mon, Jul 8, 2013 at 12:23 PM, Steven D'Aprano > <steve+comp.lang.python@pearwood.info> wrote: >> On Mon, 08 Jul 2013 10:48:03 +1000, Chris Angelico wrote: [...] >>> That means that I, as programmer, have to keep track of the nesting >>> level of subtransactions. Extremely ugly. A line of code can't be >>> moved around without first checking which transaction object to work >>> with. >> >> I feel your pain, but I wonder why we sometimes accept "a line of code >> can't be moved around" as an issue to be solved by the language. After >> all, in general most lines of code can't be moved around. > > It's not something to be solved by the language, but it's often > something to be solved by the program's design. Two lines of code that > achieve the same goal should normally look the same. This is why > Python's policy is "one obvious way to do something" rather than "spell > it five different ways in the same file to make a nightmare for other > people coming after you". Why should database queries be spelled > "trans1.query()" in one place, and "trans2.query()" in another? Is that a trick question? They probably shouldn't. But it's a big leap from that to "...and therefore `for` and `while` should introduce their own scope". > Similarly, if I want to call another function and that function needs to > use the database, why should I pass it trans3 and have that come out as > trans1 on the other side? Unnecessarily confusing. Makes much more sense > to use the same name everywhere. "Is your name not Bruce? That's going to cause a little confusion." http://www.youtube.com/watch?v=_f_p0CgPeyA -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2013-07-08 15:14 +1000 |
| Message-ID | <mailman.4364.1373260454.3114.python-list@python.org> |
| In reply to | #50116 |
On Mon, Jul 8, 2013 at 3:00 PM, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: > On Mon, 08 Jul 2013 13:11:37 +1000, Chris Angelico wrote: >> It's not something to be solved by the language, but it's often >> something to be solved by the program's design. Two lines of code that >> achieve the same goal should normally look the same. This is why >> Python's policy is "one obvious way to do something" rather than "spell >> it five different ways in the same file to make a nightmare for other >> people coming after you". Why should database queries be spelled >> "trans1.query()" in one place, and "trans2.query()" in another? > > Is that a trick question? They probably shouldn't. But it's a big leap > from that to "...and therefore `for` and `while` should introduce their > own scope". No, it's not a trick question; I was responding to Ethan's suggestion as well as yours, and he was saying pretty much that. BruceA (maybe that'll reduce the confusion?)
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2013-07-04 08:48 +0200 |
| Message-ID | <mailman.4209.1372920514.3114.python-list@python.org> |
| In reply to | #49813 |
Steven D'Aprano wrote: > Well, if I ever have more than 63,000,000 variables[1] in a function, > I'll keep that in mind. Until then, I'm pretty sure you can trivially > avoid name clashes with globals that you wish to avoid clashing with. > [1] Based on empirical evidence that Python supports names with length at > least up to one million characters long, and assuming that each character > can be an ASCII letter, digit or underscore. That would be 63**10**6. Or 53*63**999999 if I were to nitpick...
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2013-07-04 01:12 -0600 |
| Message-ID | <mailman.4210.1372921992.3114.python-list@python.org> |
| In reply to | #49813 |
On Wed, Jul 3, 2013 at 11:32 PM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
>> Python lets you do that across but not within functions.
>>
>> But Javascript/ECMAScript/whatever doesn't give you that. A var
>> declaration makes it function-local, no matter where the declaration is.
>> That's pointless. C++, on the other hand, lets you do this:
>>
>> void somefunc() {
>> for (int i=0;i<10;++i) {
>> // do something with outer i
>> for (int i=0;i<4;++i) {
>> // do something with inner i
>> }
>> // outer i is visible again
>> }
>> // neither i is visible
>> }
>
> That's truly horrible. If the cost of this "flexibility" is that I'll
> have to read, and debug, other people's code with this sort of thing, I'm
> happy to be less flexible. For what possible reason other than "because I
> can" would you want to use the same loop variable name in two nested
> loops?
It's interesting to note that while Java and C# also allow reuse of
local variable names, they do not allow local variables declared in
inner scopes to shadow variables declared in enclosing scopes, as in
the example above. But the following would be perfectly legal:
void somefunc() {
for (int i = 0; i < a.size; ++i) {
// do something with a[i]
}
for (int i = 0; i < b.size; ++i) {
// do something with b[i]
}
}
And the two i's are treated as completely separate variables here, as
arguably they should be since they're used for two distinct purposes.
[toc] | [prev] | [next] | [standalone]
| From | Dave Angel <davea@davea.name> |
|---|---|
| Date | 2013-07-04 03:06 -0400 |
| Message-ID | <mailman.4211.1372924504.3114.python-list@python.org> |
| In reply to | #49813 |
On 07/04/2013 01:32 AM, Steven D'Aprano wrote:
>
<SNIP>
>
> Well, if I ever have more than 63,000,000 variables[1] in a function,
> I'll keep that in mind.
>
<SNIP>
>
> [1] Based on empirical evidence that Python supports names with length at
> least up to one million characters long, and assuming that each character
> can be an ASCII letter, digit or underscore.
>
Well, the number wouldn't be 63,000,000. Rather it'd be 63**1000000
I probably have it wrong, but I think that looks like:
859,122,207,646,748,720,415,212,786,780,258,721,683,540,870,960,267,706,738,947,655,539,422,295,787,680,882,091,181,482,626,114,653,152,637,456,091,641,990,601,474,111,018,521,295,858,424,750,289,461,372,414,431,396,326,232,796,267,104,001
variables. (The number has 180 digits)
--
DaveA
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2013-07-04 15:52 +0000 |
| Message-ID | <51d59a36$0$29999$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #49822 |
On Thu, 04 Jul 2013 03:06:25 -0400, Dave Angel wrote: > On 07/04/2013 01:32 AM, Steven D'Aprano wrote: >> > <SNIP> >> >> Well, if I ever have more than 63,000,000 variables[1] in a function, >> I'll keep that in mind. >> > <SNIP> >> >> [1] Based on empirical evidence that Python supports names with length >> at least up to one million characters long, and assuming that each >> character can be an ASCII letter, digit or underscore. >> >> > Well, the number wouldn't be 63,000,000. Rather it'd be 63**1000000 > > I probably have it wrong, but I think that looks like: > > 859,122,207,646,748,720,415,212,786,780,258,721,683,540,870,960,267,706,738,947,655,539,422,295,787,680,882,091,181,482,626,114,653,152,637,456,091,641,990,601,474,111,018,521,295,858,424,750,289,461,372,414,431,396,326,232,796,267,104,001 > > variables. (The number has 180 digits) I think that's more than 63,000,000 :-) Thanks Dave and Peter for the correction. -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Rotwang <sg552@hotmail.co.uk> |
|---|---|
| Date | 2013-07-04 17:54 +0100 |
| Message-ID | <kr491h$g2t$1@dont-email.me> |
| In reply to | #49822 |
Sorry to be OT, but this is sending my pedantry glands haywire: On 04/07/2013 08:06, Dave Angel wrote: > On 07/04/2013 01:32 AM, Steven D'Aprano wrote: >> > <SNIP> >> >> Well, if I ever have more than 63,000,000 variables[1] in a function, >> I'll keep that in mind. >> > <SNIP> >> >> [1] Based on empirical evidence that Python supports names with length at >> least up to one million characters long, and assuming that each character >> can be an ASCII letter, digit or underscore. >> > > Well, the number wouldn't be 63,000,000. Rather it'd be 63**1000000 > > I probably have it wrong, but I think that looks like: > > 859,122,[etc.] > > > variables. (The number has 180 digits) That's 63**100. Note that 10**1000000 has 1000001 digits, and is somewhat smaller than 63**1000000. Anyway, none of the calculations that has been given takes into account the fact that names can be /less/ than one million characters long. The actual number of non-empty strings of length at most 1000000 characters, that consist only of ascii letters, digits or underscores, and that don't start with a digit, is sum(53*63**i for i in range(1000000)) == 53*(63**1000000 - 1)//62 It's perhaps worth mentioning that some non-ascii characters are allowed in identifiers in Python 3, though I don't know which ones.
[toc] | [prev] | [next] | [standalone]
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
Back to top | Article view | comp.lang.python
csiph-web