Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Documentation, assignment in expression.

Reply
Thread Tools

Documentation, assignment in expression.

 
 
Dennis Lee Bieber
Guest
Posts: n/a
 
      03-25-2012
On Sun, 25 Mar 2012 08:48:31 -0500, Tim Chase
<(E-Mail Removed)> declaimed the following in
gmane.comp.python.general:


> Yeah, it has the same structure internally, but I'm somewhat
> surprised that the DB connection object doesn't have an
> __iter__() that does something like this automatically under the
> covers.
>

I believe being able to use the connection object directly for
queries is considered a short-cut feature... If you use the longer form

con = db.connect()
cur = con.cursor()

the cursor object, in all that I've worked with, does function for
iteration

for rec in cur:
#do stuff
--
Wulfraed Dennis Lee Bieber AF6VN
http://www.velocityreviews.com/forums/(E-Mail Removed) HTTP://wlfraed.home.netcom.com/

 
Reply With Quote
 
 
 
 
mwilson@the-wire.com
Guest
Posts: n/a
 
      03-25-2012
Tim Chase wrote:

> On 03/25/12 08:11, Chris Angelico wrote:
>> On Mon, Mar 26, 2012 at 12:03 AM, Tim Chase
>> <(E-Mail Removed)> wrote:
>>> Granted, this can be turned into an iterator with a yield, making the
>>> issue somewhat moot:

>>
>> No, just moving the issue to the iterator. Your iterator has exactly
>> the same structure in it.

>
> Yeah, it has the same structure internally, but I'm somewhat
> surprised that the DB connection object doesn't have an
> __iter__() that does something like this automatically under the
> covers.


Most of my database programs wind up having the boilerplate (not tested):

def rowsof (cursor):
names = [x[0] for x in cursor.description]
r = cursor.fetchone()
while r:
yield dict (zip (names, r))
r = cursor.fetchone()


Mel.
>
>> Personally, I quite like assignment-in-conditional notation. Yes, it's
>> a pretty common cause of problems; but what happened to the
>> "consenting adults" policy? Python permits operator overloading and
>> even the reassignment of builtins, both of which can cause similar
>> confusion.

>
> In my past years of C programming, I've accidentally omitted the
> second "=" in a comparison test numerous times, requiring me to
> track down the missing character. When I finally catch it, it's
> obvious what the problem is, but I've come to love having Python
> yell at me contextually.
>
>> But, that's the choice Python's made. And being able to use the same
>> symbol for assignment and comparison does have its advantages.

>
> The old curmudgeon in me likes the Pascal method of using "=" for
> equality-testing, and ":=" for assignment which feels a little
> closer to mathematical use of "=".
>
> -tkc


 
Reply With Quote
 
 
 
 
Dennis Lee Bieber
Guest
Posts: n/a
 
      03-26-2012
On Sun, 25 Mar 2012 19:09:12 -0400, (E-Mail Removed) declaimed the
following in gmane.comp.python.general:


> Most of my database programs wind up having the boilerplate (not tested):
>
> def rowsof (cursor):
> names = [x[0] for x in cursor.description]
> r = cursor.fetchone()
> while r:
> yield dict (zip (names, r))
> r = cursor.fetchone()
>


In my (limited) experience, the main loop above could be replaced
with:

for r in cursor:
yield dict(zip(names, r))

Though some DB adapters provide a "dictionary cursor" that already
does what this modules does; or provides a way to specify a subclassed
cursor that implements the dictionary cursor internally.
--
Wulfraed Dennis Lee Bieber AF6VN
(E-Mail Removed) HTTP://wlfraed.home.netcom.com/

 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      03-26-2012
On Sun, 25 Mar 2012 08:03:14 -0500, Tim Chase wrote:

> I think the complaint was backed by a bad example. Perhaps a DB example
> works better. With assignment allowed in an evaluation, you'd be able
> to write
>
> while data = conn.fetchmany():
> for row in data:
> process(row)


Yes, but why would you want to? Apart from making your code hard to read.
Better written as:

while data = conn.fetchmany(): # THIS IS NOT A TYPO
for row in data:
process(row)


When you need to write a comment explaining that something isn't a typo,
that's a good clue that you shouldn't do it *wink*

But seriously, assignment as an expression is a pretty major code-smell.
Even when it's innocent, it should still fire off warning alarms, because
how do you know if it's innocent or not until you've studied the code?

(Comments, like the above, are prone to get out of date with the code,
and can't be entirely trusted.)

Python avoids this code smell by prohibiting assignment as an expression.
Functional languages avoid it by prohibiting assignment. Other languages
may choose to do differently. If all languages did exactly what C does,
they'd all be C.

(I seem to recall a language that used a single = for both assignment and
equality testing, guessing which one you meant from context. BASIC
perhaps? Whatever it was, I'm pretty sure they regretted it.)


> whereas you have to write
>
> while True:
> data = conn.fetchmany()
> if not data: break
> for row in data:
> process(row)


Or even:

data = 'SENTINEL' # Any true value will do.
while data:
data = conn.fetchmany()
for row in data:
process(row)


There's no need to break out of the while loop early, because `for row in
<empty>` is a null-op.




--
Steven
 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      03-26-2012
On Sun, 25 Mar 2012 17:16:16 +0200, Kiuhnm wrote:

> On 3/25/2012 15:48, Tim Chase wrote:
>> The old curmudgeon in me likes the Pascal method of using "=" for
>> equality-testing, and ":=" for assignment which feels a little closer
>> to mathematical use of "=".

>
> Unfortunately, ":=" means "is defined as" in mathematics. The "right"
> operator would have been "<-".


That's hardly universal. In approx 20 years of working with mathematics
textbooks, I've never seen := used until today.

I see that Wikipedia lists no fewer than seven different symbols for "is
defined as":

http://en.wikipedia.org/wiki/Table_o...atical_symbols

including the one I'm familiar with, ≝, or "def" over "=".

Besides, just because mathematicians use a symbol, doesn't mean
programming languages can't use it for something else.



--
Steven
 
Reply With Quote
 
Devin Jeanpierre
Guest
Posts: n/a
 
      03-26-2012
On Sun, Mar 25, 2012 at 11:16 AM, Kiuhnm
<(E-Mail Removed)> wrote:
> On 3/25/2012 15:48, Tim Chase wrote:
>>
>> The old curmudgeon in me likes the Pascal method of using "=" for
>> equality-testing, and ":=" for assignment which feels a little closer to
>> mathematical use of "=".

>
>
> Unfortunately, ":=" means "is defined as" in mathematics. The "right"
> operator would have been "<-".



"Is defined as" is actually pretty reasonable. "Define this to be
that" is a common way to speak about assignment. Its only difference
is the present tense. For example, in Python, "def" stands for
"define", but we can overwrite previous definitions::

def f(x): return x
def f(x): return 2
f(3) == 2

In fact, in pretty every programming language that I know of with a
"define" assignment verb, this is so. For example, in Scheme, x is 2
at the end::

(define x 1)
(define x 2)
x

-- Devin
 
Reply With Quote
 
Tim Chase
Guest
Posts: n/a
 
      03-26-2012
On 03/25/12 17:59, Dennis Lee Bieber wrote:
> On Sun, 25 Mar 2012 08:48:31 -0500, Tim Chase
>> Yeah, it has the same structure internally, but I'm somewhat
>> surprised that the DB connection object doesn't have an
>> __iter__() that does something like this automatically under the
>> covers.
>>

> I believe being able to use the connection object directly for
> queries is considered a short-cut feature... If you use the longer form
>
> con = db.connect()
> cur = con.cursor()
>
> the cursor object, in all that I've worked with, does function for
> iteration
>
> for rec in cur:
> #do stuff


Interesting. Either this is something special for a particular
DB back-end, or has been added since I went hunting (back with
mxODBC and Python2.4). I wouldn't be surprised if the latter was
the case, as my code is nigh identical to yours.

conn = db.DriverConnect(connection_string)
cursor = conn.cursor()
cursor.execute(sql, params)
for row in cursor: # in the above 2.4 + mxODBC, this fails
process(row)

I'd be interested to know the underlying implementation's
efficiency, hopefully using .fetchmany() under the hood. My
understanding is that the .fetchmany() loop is the best way to do
it, as the .fetchone() gets chatty with the DB (but is more
efficient if you only need one row from a multi-result query),
and the .fetchall() can blow out memory on large datasets.

-tkc




 
Reply With Quote
 
Jussi Piitulainen
Guest
Posts: n/a
 
      03-26-2012
Kiuhnm writes:
> On 3/26/2012 10:52, Devin Jeanpierre wrote:
> > On Sun, Mar 25, 2012 at 11:16 AM, Kiuhnm
> > <(E-Mail Removed)> wrote:
> >> On 3/25/2012 15:48, Tim Chase wrote:
> >>>
> >>> The old curmudgeon in me likes the Pascal method of using "=" for
> >>> equality-testing, and ":=" for assignment which feels a little closer to
> >>> mathematical use of "=".
> >>
> >>
> >> Unfortunately, ":=" means "is defined as" in mathematics. The "right"
> >> operator would have been "<-".

> >
> >
> > "Is defined as" is actually pretty reasonable. "Define this to be
> > that" is a common way to speak about assignment. Its only difference
> > is the present tense. For example, in Python, "def" stands for
> > "define", but we can overwrite previous definitions::
> >
> > def f(x): return x
> > def f(x): return 2
> > f(3) == 2
> >
> > In fact, in pretty every programming language that I know of with a
> > "define" assignment verb, this is so. For example, in Scheme, x is 2
> > at the end::
> >
> > (define x 1)
> > (define x 2)
> > x

>
> When you write
> (define x 1)
> (define x 2)
> x
> or, in F# and OCaml,
> let x = 1
> let x = 2
> x
> you're saying
> x = 1
> {
> x = 2
> x
> }
> You don't modify 'x': you hide it by defining another "value" (not
> variable) with the same name.
> Indeed,
> let x = 1
> let x = 2
> x
> is shorthand for
> let x = 1 in
> let x = 2 in
> x


No, Devin is right about Scheme. On "top level" re-definition is
interpreted as assignment. The following mean the same:

(define x 1) (define x 2) x
(define x 1) (set! x 2) x

Local definitions in the beginning of a "body" do not allow duplicate
names at all. The following mean the same:

(let () (define x 1) (define y 2) x)
(letrec* ((x 1) (y 2)) x) ;letrec in older versions (not sure of R6RS)

But (let () (define x 1) (define x 2) x) is still an error. Some
implementations may give it a meaning. Not sure.
 
Reply With Quote
 
mwilson@the-wire.com
Guest
Posts: n/a
 
      03-26-2012
Dennis Lee Bieber wrote:

> On Sun, 25 Mar 2012 19:09:12 -0400, (E-Mail Removed) declaimed the
> following in gmane.comp.python.general:
>
>
>> Most of my database programs wind up having the boilerplate (not tested):
>>
>> def rowsof (cursor):
>> names = [x[0] for x in cursor.description]
>> r = cursor.fetchone()
>> while r:
>> yield dict (zip (names, r))
>> r = cursor.fetchone()
>>

>
> In my (limited) experience, the main loop above could be replaced
> with:
>
> for r in cursor:
> yield dict(zip(names, r))


I think your experience is more recent than mine. I'll change my
boilerplate next time around.

Mel.

 
Reply With Quote
 
Thomas Rachel
Guest
Posts: n/a
 
      03-26-2012
Am 26.03.2012 00:59 schrieb Dennis Lee Bieber:

> If you use the longer form
>
> con = db.connect()
> cur = con.cursor()
>
> the cursor object, in all that I've worked with, does function for
> iteration


I use this form regularly with MySQLdb and am now surprised to see that
this is optional according to http://www.python.org/dev/peps/pep-0249/.

So a database cursor is not required to be iterable, alas.


Thomas

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Assignment operator self-assignment check Chris C++ 34 09-26-2006 04:26 AM
Augument assignment versus regular assignment nagy Python 36 07-20-2006 07:24 PM
Question about interference and Wireless Channel Assignment HOESan Wireless Networking 4 09-04-2004 08:36 PM
Comparison of Bit Vectors in a Conditional Signal Assignment Statement Anand P Paralkar VHDL 2 08-04-2003 08:40 PM
Help: conditional attribute assignment itsme VHDL 1 07-23-2003 03:26 PM



Advertisments