Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-04 Thread Chris Angelico
On Fri, Dec 5, 2014 at 9:10 AM, Wolfgang Maier
 wrote:
> which I read as there has been a stepwise transition between 2.5 and 2.7 so
> that 2.7 now behaves like Python 3 even without the __future__ statement.
> OTOH, I believe you, of course, if you're saying implicit relative imports
> are working just fine in 2.7, but then how to interpret the "In Python 2.7
> the __future__ statement is not needed." above ?

Hmm. To be honest, I'm not sure. The Python 2.7 __future__ module
claims that absolute_import became standard in 3.0, not 2.7, which
seems to conflict with what you're seeing.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-04 Thread Wolfgang Maier

On 04.12.2014 22:30, Chris Angelico wrote:

On Fri, Dec 5, 2014 at 7:56 AM, Wolfgang Maier
 wrote:

On 04.12.2014 19:05, Chris Angelico wrote:



With os.path it definitely is. With the actual code in question, it's
a Python 2.7 project that mostly uses relative imports - inside
package.module1 is "import module2" etc - and I was writing an
external script that calls on one of the modules.



What ? I'm usually thinking Python 3 not 2 and I'm never sure which Python
2.x has backported which feature of 3, but I thought implicit relative
imports like you seem to describe are not working in 2.7 ?


Hmm, I'm not sure, but certainly it does seem to work that way. Typing
"import foo" from inside a package will import foo.py from the package
directory. I haven't dug into the details of _why_, and if ever the
project shifts to Python 3 (which I would like it to), we might have
to change some of the import lines, but I'd still like to be able to
reference "foo.bar" as meaning the "bar" top-level object in foo.py.



I checked what the docs say about this and it is totally confusing (at 
least me):


https://docs.python.org/3/howto/pyporting.html#from-future-import-absolute-import 
says:


"
from __future__ import absolute_import

Implicit relative imports (e.g., importing spam.bacon from within 
spam.eggs with the statement import bacon) do not work in Python 3. This 
future statement moves away from that and allows the use of explicit 
relative imports (e.g., from . import bacon).


In Python 2.5 you must use the __future__ statement to get to use 
explicit relative imports and prevent implicit ones. In Python 2.6 
explicit relative imports are available without the statement, but you 
still want the __future__ statement to prevent implicit relative 
imports. In Python 2.7 the __future__ statement is not needed. In other 
words, unless you are only supporting Python 2.7 or a version earlier 
than Python 2.5, use this __future__ statement.

"

which I read as there has been a stepwise transition between 2.5 and 2.7 
so that 2.7 now behaves like Python 3 even without the __future__ statement.
OTOH, I believe you, of course, if you're saying implicit relative 
imports are working just fine in 2.7, but then how to interpret the "In 
Python 2.7 the __future__ statement is not needed." above ?


Wolfgang

--
https://mail.python.org/mailman/listinfo/python-list


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-04 Thread Chris Angelico
On Fri, Dec 5, 2014 at 7:56 AM, Wolfgang Maier
 wrote:
> On 04.12.2014 19:05, Chris Angelico wrote:
>>
>>
>> With os.path it definitely is. With the actual code in question, it's
>> a Python 2.7 project that mostly uses relative imports - inside
>> package.module1 is "import module2" etc - and I was writing an
>> external script that calls on one of the modules.
>
>
> What ? I'm usually thinking Python 3 not 2 and I'm never sure which Python
> 2.x has backported which feature of 3, but I thought implicit relative
> imports like you seem to describe are not working in 2.7 ?

Hmm, I'm not sure, but certainly it does seem to work that way. Typing
"import foo" from inside a package will import foo.py from the package
directory. I haven't dug into the details of _why_, and if ever the
project shifts to Python 3 (which I would like it to), we might have
to change some of the import lines, but I'd still like to be able to
reference "foo.bar" as meaning the "bar" top-level object in foo.py.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-04 Thread Wolfgang Maier

On 04.12.2014 19:05, Chris Angelico wrote:


With os.path it definitely is. With the actual code in question, it's
a Python 2.7 project that mostly uses relative imports - inside
package.module1 is "import module2" etc - and I was writing an
external script that calls on one of the modules.


What ? I'm usually thinking Python 3 not 2 and I'm never sure which 
Python 2.x has backported which feature of 3, but I thought implicit 
relative imports like you seem to describe are not working in 2.7 ?


Wolfgang

--
https://mail.python.org/mailman/listinfo/python-list


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-04 Thread Chris Angelico
On Fri, Dec 5, 2014 at 4:36 AM, Jean-Michel Pichavant
 wrote:
> I know you specifically stated you didn't want to do this but
>
> import os
>
> os.path.isfile()
>
> is the best option imo, especially from the reader point of view ("Namespaces 
> are one honking great idea").

With os.path it definitely is. With the actual code in question, it's
a Python 2.7 project that mostly uses relative imports - inside
package.module1 is "import module2" etc - and I was writing an
external script that calls on one of the modules. So it makes sense to
reference it through the code the exact same way, as "module.blah"
rather than "package.module.blah".

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-04 Thread Ethan Furman
On 12/03/2014 03:02 AM, Chris Angelico wrote:
> 
> Throughout the code, I want to refer to "path.split()",
> "path.isfile()", etc, without the "os." in front of them. I could do
> either of these:
> 
> import os.path as path
> from os import path
> 
> Which one would you recommend? Does it depend on context?

I recommend the one with less typing.  ;)

--
~Ethan~



signature.asc
Description: OpenPGP digital signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-04 Thread Ethan Furman
On 12/04/2014 09:36 AM, Jean-Michel Pichavant wrote:
> 
> I know you specifically stated you didn't want to do this but
> 
>   import os
> 
>   os.path.isfile()
> 
> is the best option imo, especially from the reader point of view ("Namespaces 
> are one honking great idea").

But, "Flat is better than nested" !  ;)

--
~Ethan~



signature.asc
Description: OpenPGP digital signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-04 Thread Jean-Michel Pichavant
- Original Message -
> From: "Chris Angelico" 
> To: python-list@python.org
> Sent: Wednesday, 3 December, 2014 12:02:17 PM
> Subject: Style question: Importing modules from packages - 'from' vs 'as'
> 
> When importing a module from a subpackage, it's sometimes convenient
> to refer to it throughout the code with a one-part name rather than
> two. I'm going to use 'os.path' for the examples, but my actual
> use-case is a custom package where the package name is, in the
> application, quite superfluous.
> 
> Throughout the code, I want to refer to "path.split()",
> "path.isfile()", etc, without the "os." in front of them. I could do
> either of these:
> 
> import os.path as path
> from os import path
> 
> Which one would you recommend? Does it depend on context?
> 
> An "as" import works only if it's a module in a package, where the
> "from" import can also import other objects (you can't go "import
> pprint.pprint as pprint"). I'm fairly sure that's an argument... on
> one side or another. :)
> 
> Thoughts?
> 
> ChrisA
> --
> https://mail.python.org/mailman/listinfo/python-list
> 

I know you specifically stated you didn't want to do this but

import os

os.path.isfile()

is the best option imo, especially from the reader point of view ("Namespaces 
are one honking great idea").



-- IMPORTANT NOTICE: 

The contents of this email and any attachments are confidential and may also be 
privileged. If you are not the intended recipient, please notify the sender 
immediately and do not disclose the contents to any other person, use it for 
any purpose, or store or copy the information in any medium. Thank you.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-04 Thread Wolfgang Maier

On 12/03/2014 12:02 PM, Chris Angelico wrote:

When importing a module from a subpackage, it's sometimes convenient
to refer to it throughout the code with a one-part name rather than
two. I'm going to use 'os.path' for the examples, but my actual
use-case is a custom package where the package name is, in the
application, quite superfluous.

Throughout the code, I want to refer to "path.split()",
"path.isfile()", etc, without the "os." in front of them. I could do
either of these:

import os.path as path
from os import path

Which one would you recommend? Does it depend on context?



One argument not yet brought up by anyone else:

if you ever wanted to make the module part of your own package and turn 
the import into a relative one, only the second, but not the first form 
lets you replace the package name with . :


from . import path (while import .path is a SyntaxError, so you'd need a 
slightly more complicated rewrite).


Wolfgang


--
https://mail.python.org/mailman/listinfo/python-list


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-03 Thread Terry Reedy

On 12/3/2014 6:02 AM, Chris Angelico wrote:

When importing a module from a subpackage, it's sometimes convenient
to refer to it throughout the code with a one-part name rather than
two. I'm going to use 'os.path' for the examples, but my actual
use-case is a custom package where the package name is, in the
application, quite superfluous.

Throughout the code, I want to refer to "path.split()",
"path.isfile()", etc, without the "os." in front of them. I could do
either of these:

import os.path as path
from os import path

Which one would you recommend? Does it depend on context?


I confirmed that they do the same thing for submodules.
>>> import os.path as pth
>>> from os import path
>>> pth

>>> path

>>> id(pth)
4319096
>>> id(path)
4319096

I and most code I have seen uses "from tkinter import ttk".


An "as" import works only if it's a module in a package, where the
"from" import can also import other objects (you can't go "import
pprint.pprint as pprint"). I'm fairly sure that's an argument... on
one side or another.


"import tkinter.ttk as ttk" makes it clear that ttk is a module rather 
than, say, a class.  That might make things easier for the reader.  On 
the other hand, duplication implies that there might be a real renaming, 
so having to compare to see that there is not, is extra work.


from idlelib import EditorWindow
import idlelib.EditorWindow as EditorWindow

--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-03 Thread Ian Kelly
On Dec 3, 2014 4:34 AM, "Chris Angelico"  wrote:
>
> On Wed, Dec 3, 2014 at 10:27 PM, Peter Otten <__pete...@web.de> wrote:
> > Don't repeat yourself, so
> >
> > from os import path
> >
> > always. On the other hand I have never thought about actual renames, e.
g.
> >
> > from os import path as stdpath
> >
> > versus
> >
> > import os.path as stdpath
> >
> > I think I'd use the latter as it looks simpler.
>
> Thanks, Peter and Tim. Keeping DRY is worth doing (the more so as it's
> raining as I type this...), and I won't be renaming in this, so the
> from-import wins - but as Tim says, it's a close race.

To offer a counterpoint, the from import is also less explicit. With
"import os.path as path", path must be a module. With the from import, path
could be either a module or just any attribute of the os module.

My preference when importing modules is to use the fully qualified name --
os.path, not path. If I do a submodule import, I'm probably assigning a
local name anyway, so I still prefer the "import as" over the "from import
as".
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-03 Thread Chris Angelico
On Wed, Dec 3, 2014 at 10:27 PM, Peter Otten <__pete...@web.de> wrote:
> Don't repeat yourself, so
>
> from os import path
>
> always. On the other hand I have never thought about actual renames, e. g.
>
> from os import path as stdpath
>
> versus
>
> import os.path as stdpath
>
> I think I'd use the latter as it looks simpler.

Thanks, Peter and Tim. Keeping DRY is worth doing (the more so as it's
raining as I type this...), and I won't be renaming in this, so the
from-import wins - but as Tim says, it's a close race.

I do like the turn-around times on this list. Although, of course,
it's entirely possible there'll be a week's worth of posts coming when
someone hits on a controversial subaspect of the question somewhere;
any volunteers? :) :)

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-03 Thread Peter Otten
Chris Angelico wrote:

> When importing a module from a subpackage, it's sometimes convenient
> to refer to it throughout the code with a one-part name rather than
> two. I'm going to use 'os.path' for the examples, but my actual
> use-case is a custom package where the package name is, in the
> application, quite superfluous.
> 
> Throughout the code, I want to refer to "path.split()",
> "path.isfile()", etc, without the "os." in front of them. I could do
> either of these:
> 
> import os.path as path
> from os import path
> 
> Which one would you recommend? Does it depend on context?

Don't repeat yourself, so

from os import path

always. On the other hand I have never thought about actual renames, e. g.

from os import path as stdpath

versus

import os.path as stdpath

I think I'd use the latter as it looks simpler.

> An "as" import works only if it's a module in a package, where the
> "from" import can also import other objects (you can't go "import
> pprint.pprint as pprint"). I'm fairly sure that's an argument... on
> one side or another. :)

In theory you could sometimes catch erroneous assumptions about 
pprint.pprint's type. But I don't care.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Style question: Importing modules from packages - 'from' vs 'as'

2014-12-03 Thread Tim Delaney
On 3 December 2014 at 22:02, Chris Angelico  wrote:

>
> import os.path as path
> from os import path
>

Bah - deleted the list and sent directly to Chris ... time to go to bed.

The advantage of the former is that if you want to use a different name,
it's a smaller change. But the disadvantage of the former is that if you
*don't* want to rename, it violates DRY (don't repeat yourself).

The difference is so marginal that I'd leave it to personal preference, and
wouldn't pull someone up for either in a code review.

Tim Delaney
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Style question -- plural of class name?

2013-05-09 Thread Robert Kern

On 2013-05-08 21:20, Roy Smith wrote:

FooEntry is a class.  How would you describe a list of these in a
docstring?

"A list of FooEntries"

"A list of FooEntrys"

"A list of FooEntry's"

"A list of FooEntry instances"

The first one certainly sounds the best, but it seems wierd to change
the spelling of the class name to make it plural.


I'm using services like Github more and more to talk about code, so I have taken 
to adopting its inline markup for `code` when referring to identifiers. Thus, I 
will often write


  A list of `FooEntry`s

But I don't mind

  A list of FooEntries

Hopefully there isn't also a `FooEntries` class.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
 that is made terrible by our own mad attempt to interpret it as though it had
 an underlying truth."
  -- Umberto Eco

--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question -- plural of class name?

2013-05-09 Thread Neil Cerutti
On 2013-05-09, Jussi Piitulainen  wrote:
> Neil Cerutti writes:
>> If there's no chance for confusion between a class named
>> FooEntry and another named FooEntries, then the first attempt
>> seems best. Pluralize a class name by following the usual
>> rules, e.g., "strings" and "ints".
>
> Like "strings" would be "foo entries". Which might work well.
>
> (I mean, isn't the class named "str"?)

Yeah, that's not such a good Python example. I used it to replace
"chars" and felt good at the time. ;)

-- 
Neil Cerutti
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question -- plural of class name?

2013-05-09 Thread Jussi Piitulainen
Neil Cerutti writes:

> If there's no chance for confusion between a class named FooEntry
> and another named FooEntries, then the first attempt seems best.
> Pluralize a class name by following the usual rules, e.g.,
> "strings" and "ints".

Like "strings" would be "foo entries". Which might work well.

(I mean, isn't the class named "str"?)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question -- plural of class name?

2013-05-09 Thread Neil Cerutti
On 2013-05-08, Denis McMahon  wrote:
> On Wed, 08 May 2013 16:20:48 -0400, Roy Smith wrote:
>
>> FooEntry is a class.  How would you describe a list of these in a
>> docstring?
>> 
>> "A list of FooEntries"
>> 
>> "A list of FooEntrys"
>> 
>> "A list of FooEntry's"
>> 
>> "A list of FooEntry instances"
>> 
>> The first one certainly sounds the best, but it seems wierd to change
>> the spelling of the class name to make it plural.
>
> I wouldn't use an apostrophe for pluralisation.

If there's no chance for confusion between a class named FooEntry
and another named FooEntries, then the first attempt seems best.
Pluralize a class name by following the usual rules, e.g.,
"strings" and "ints".

-- 
Neil Cerutti
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question -- plural of class name?

2013-05-09 Thread Thomas Rachel

Am 09.05.2013 02:38 schrieb Colin J. Williams:

On 08/05/2013 4:20 PM, Roy Smith wrote:


"A list of FooEntry's"  +1


Go back to school. Both of you...

That is NOT the way to build a plural form...


Thomas
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question -- plural of class name?

2013-05-08 Thread Cameron Simpson
On 09May2013 00:02, Steven D'Aprano  
wrote:
| On Wed, 08 May 2013 16:20:48 -0400, Roy Smith wrote:
| > "A list of FooEntry's"
| 
| "Here come's an S! Quick, jam on an apostrophe!"
| 
| This is called the grocer's apostrophe, and is universally held in 
| contempt no matter what variant of English you write in. Don't do this.
| 
| The only acceptable use of an apostrophe to make a plural is if the thing 
| being pluralised is a single letter. E.g. one a, two a's.

Frankly, not even then for me. I spell that "one A, two As".

| > "A list of FooEntry instances"
| 
| This is also acceptable, although a little wordy. Do you write "a list of 
| strings" or "a list of str instances"?

How about "a FooEntry list"?
-- 
Cameron Simpson 

Yes Officer, yes Officer, I will Officer. Thank you.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question -- plural of class name?

2013-05-08 Thread Colin J. Williams

On 08/05/2013 4:20 PM, Roy Smith wrote:

FooEntry is a class.  How would you describe a list of these in a
docstring?

"A list of FooEntries"  0

"A list of FooEntrys"   -1

"A list of FooEntry's"  +1

"A list of FooEntry instances"  No FooEntry is specified as a class.

The first one certainly sounds the best, but it seems wierd to change
the spelling of the class name to make it plural.



Colin W.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question -- plural of class name?

2013-05-08 Thread Steven D'Aprano
On Wed, 08 May 2013 15:33:07 -0500, Skip Montanaro wrote:

> This one:
> 
>> "A list of FooEntry instances"
> 
> Besides the obvious spelling issues in the others, it's not immediately
> clear if the list contains just FooEntry instances, FooEntry classes
> (perhaps subclasses) or a mix of the two.  #4 makes it clear.


I don't think this is a real issue. There isn't normally any ambiguity 
between instances and subclasses. When you read "a list of ints", do you 
assume that the list looks like [int, MyInt, AnotherInt, FooInt] or do 
you expect it to look like [2, 7, 6, 1]?

The normal interpretation of "one or more Foo" is that we're talking 
about Foo *instances*, not subclasses of Foo. If that is not that case, 
then the onus is on the author of the documentation to make it clear that 
they are talking about subclasses.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question -- plural of class name?

2013-05-08 Thread Chris Angelico
On Thu, May 9, 2013 at 6:20 AM, Roy Smith  wrote:
> "A list of FooEntry's"

Only if you put another apostrophe in:

"A list of 'FooEntry's"

But the delimited style is almost never of use. I'd go for this only
if there were some sort of automated markup being applied - if the
word FooEntry were turned into a hyperlink or something.

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question -- plural of class name?

2013-05-08 Thread Steven D'Aprano
On Wed, 08 May 2013 16:20:48 -0400, Roy Smith wrote:

> FooEntry is a class.  How would you describe a list of these in a
> docstring?


Which language are you writing your docstrings in? Obey the normal rules 
of spelling, grammar and punctuation for your language, which I assume is 
English.


> "A list of FooEntries"

Perfectly acceptable.


> "A list of FooEntrys"

There is no standard variant or dialect of English (British English, 
American English, etc.) that pluralises Entry as Entrys, so that would be 
"absolutely not".


> "A list of FooEntry's"

"Here come's an S! Quick, jam on an apostrophe!"

This is called the grocer's apostrophe, and is universally held in 
contempt no matter what variant of English you write in. Don't do this.

The only acceptable use of an apostrophe to make a plural is if the thing 
being pluralised is a single letter. E.g. one a, two a's.

 
> "A list of FooEntry instances"

This is also acceptable, although a little wordy. Do you write "a list of 
strings" or "a list of str instances"?


> The first one certainly sounds the best, but it seems wierd to change
> the spelling of the class name to make it plural.

No weirder (note spelling) than changing any other noun. Whether you 
change "int" to "ints" or FooEntry" to "FooEntries", you're still 
changing it. That's how you make it plural.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question -- plural of class name?

2013-05-08 Thread Denis McMahon
On Wed, 08 May 2013 16:20:48 -0400, Roy Smith wrote:

> FooEntry is a class.  How would you describe a list of these in a
> docstring?
> 
> "A list of FooEntries"
> 
> "A list of FooEntrys"
> 
> "A list of FooEntry's"
> 
> "A list of FooEntry instances"
> 
> The first one certainly sounds the best, but it seems wierd to change
> the spelling of the class name to make it plural.

I wouldn't use an apostrophe for pluralisation.

The Normal pluralisation of FooEntry would be FooEntries. Who are you 
expecting to read the docstring? English majors, grammar nazis, wikipedia 
editors, programmers, or all 4?

-- 
Denis McMahon, denismfmcma...@gmail.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question -- plural of class name?

2013-05-08 Thread Ian Kelly
On Wed, May 8, 2013 at 2:37 PM, John Downs  wrote:
> On Wed, May 8, 2013 at 4:20 PM, Roy Smith  wrote:
>>
>> FooEntry is a class.  How would you describe a list of these in a
>> docstring?
>>
>> "A list of FooEntries"
>>
>> "A list of FooEntrys"
>>
>> "A list of FooEntry's"
>>
>> "A list of FooEntry instances"
>>
>> The first one certainly sounds the best, but it seems wierd to change
>> the spelling of the class name to make it plural.
>> --
>> http://mail.python.org/mailman/listinfo/python-list
>
>
> How about: "A list with elements of type FooEntry"?  I also like the last
> one: "A list of FooEntry instances".

list

*ducks*
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question -- plural of class name?

2013-05-08 Thread John Downs
On Wed, May 8, 2013 at 4:20 PM, Roy Smith  wrote:

> FooEntry is a class.  How would you describe a list of these in a
> docstring?
>
> "A list of FooEntries"
>
> "A list of FooEntrys"
>
> "A list of FooEntry's"
>
> "A list of FooEntry instances"
>
> The first one certainly sounds the best, but it seems wierd to change
> the spelling of the class name to make it plural.
> --
> http://mail.python.org/mailman/listinfo/python-list
>

How about: "A list with elements of type FooEntry"?  I also like the last
one: "A list of FooEntry instances".
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question -- plural of class name?

2013-05-08 Thread Skip Montanaro
This one:

> "A list of FooEntry instances"

Besides the obvious spelling issues in the others, it's not
immediately clear if the list contains just FooEntry instances,
FooEntry classes (perhaps subclasses) or a mix of the two.  #4 makes
it clear.

Skip
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: metaclass self vs cls?

2012-07-17 Thread Steven D'Aprano
On Tue, 17 Jul 2012 05:23:22 -0700, Michele Simionato wrote:

> The standard is to use `cls`. In the __new__ method you can use `mcl` or
> `meta`.

Thanks to everyone who answered.

I think I will stick with "meta" and "cls".


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: metaclass self vs cls?

2012-07-17 Thread Ian Kelly
On Tue, Jul 17, 2012 at 12:10 AM, alex23  wrote:
> On Jul 17, 1:29 am, Steven D'Aprano  +comp.lang.pyt...@pearwood.info> wrote:
>> Here's a style question for you: in a metaclass, what should I call the
>> instance parameter of methods, "cls" or "self"?
>
> Maybe portmanteu it as "clasself"? :)

What is this, 1st edition D&D?  Elf is a race, not a class.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: metaclass self vs cls?

2012-07-17 Thread Ian Kelly
On Tue, Jul 17, 2012 at 6:23 AM, Michele Simionato
 wrote:
> The standard is to use `cls`. In the __new__ method you can use `mcl` or 
> `meta`.

I've also seen `mcs` a fair amount.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: metaclass self vs cls?

2012-07-17 Thread Michele Simionato
The standard is to use `cls`. In the __new__ method you can use `mcl` or `meta`.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: metaclass self vs cls?

2012-07-16 Thread Terry Reedy

On 7/16/2012 11:29 AM, Steven D'Aprano wrote:

Here's a style question for you: in a metaclass, what should I call the
instance parameter of methods, "cls" or "self"?

class ExampleMeta(type):
 def method(self, *args): ...

I'm not quite sure if that feels right. On the one hand, self is the
ExampleMeta instance alright... but on the other, self is actually a
class, so I feel I want to call it "cls" rather than "self", which makes
it more obvious that you're looking at a metaclass.


I have never seriously written a metaclass, but as a reader I would 
prefer 'cls'.



On the third-hand, it may be confusing that the argument is called "cls"
but not decorated with classdecorator.


To me, that reinforces 'looking as a metaclass'.

An @classmethod in a class is a class method specific to the particular 
class. A method in a metaclass is a method common to all classes of the 
metaclass. They could be written differently, yet calling the first 
param 'cls' either way seems reasonable.



I'm very slightly leaning towards writing metaclasses like this:

class ExampleMeta(type):
 def __new__(meta, *args): ...
 def method(cls, *args): ...

class Example(metaclass=ExampleMeta):
 def another_method(self): ...



What do others do?


Not too many people write real metaclasses. Python lets you chose. Have 
you looked at the C code of type? (Not that you are bound by it.)


--
Terry Jan Reedy



--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question (Poll)

2012-03-15 Thread Jon Clements
On Wednesday, 14 March 2012 21:16:05 UTC, Terry Reedy  wrote:
> On 3/14/2012 4:49 PM, Arnaud Delobelle wrote:
> > On 14 March 2012 20:37, Croepha  wrote:
> >> Which is preferred:
> >>
> >> for value in list:
> >>   if not value is another_value:
> >> value.do_something()
> >> break
> 
> Do you really mean 'is' or '=='?
> 
> If you mean x is not y, write it that way.
> 'not x is y' can be misread and misunderstood, depending on whether
> the 'is' is true or not.
> 
>  >>> not 1 is 1
> False
>  >>> not (1 is 1)
> False
>  >>> (not 1) is 1
> False
> 
> Does not matter how read.
> 
>  >>> not (1 is 0)
> True
>  >>> (not 1) is 0
> False
>  >>> not 1 is 0
> True
> 
> Does matter how read.
> 
> >> if list and not list[0] is another_value:
> >>   list[0].do_something()
> 
> Or
> try:
>value = mylist[0]
>if value is not another_value: value.dosomething
> except IndexError:
>pass
> 
> I would not do this in this case of index 0, but if the index were a 
> complicated expression or expensive function call, making 'if list' an 
> inadequate test, I might.
> 
> > Hard to say, since they don't do the same thing :)
> >
> > I suspect you meant:
> >
> > for value in list:
> > if not value is another_value:
> > value.do_something()
> > break
> >
> > I always feel uncomfortable with this because it's misleading: a loop
> > that never loops.
> 
> I agree. Please do not do this in public ;-).
> 
> -- 
> Terry Jan Reedy

I'm not sure it's efficient or even if I like it, but it avoids try/except and 
the use of a for loop.

if next( iter(mylist), object() ) is not another_value:
# ...

Just my 2p,

Jon.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question (Poll)

2012-03-14 Thread Chris Angelico
On Thu, Mar 15, 2012 at 7:37 AM, Croepha  wrote:
> Which is preferred:
>
> for value in list:
>  if not value is another_value:
>    value.do_something()
>    break
>
> --or--
>
> if list and not list[0] is another_value:
>  list[0].do_something()
>
> Comments are welcome, Thanks

General principle: Make the code look like what it's doing. I don't
mean text art and making code in the shape of pi that prints the
digits of pi (although that can be awesome too), but more that a loop
should not be used when you don't intend for it to loop. Consider the
For-Case Paradigm[1] and the amazing confusion value that it can
offer. A loop needn't execute more than once (it needn't even execute
the first time), but it should at least have the _potential_ to
execute the same code multiple times, otherwise it's hardly a loop.

I had a particularly nasty example of a loop-that-wasn't-a-loop at
work a while ago; it was PHP, not Python, so I won't share it here,
but it had a do-while loop and an insidious bug in it. Very tricky.

ChrisA
[1] http://thedailywtf.com/Articles/The_FOR-CASE_paradigm.aspx
-- 
http://mail.python.org/mailman/listinfo/python-list


RE: Style question (Poll)

2012-03-14 Thread Prasad, Ramit
> > Only use 'is' if you are looking for objects like True,
> > False, None or something that MUST be exactly the same object.
> 
> I've rarely seen valid uses of 'is True' or 'is False'.

It can be useful when you think something might be None or False. Although,
I suppose you could always just use 'is None' instead.

>>> 1 == True
True
>>> 1 is True
False
>>> 0 == False
True
>>> 0 is False
False

Granted, the above example is a pretty facetious case; not sure I 
can come up with a reasonably real world use case. 

Ramit


Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology
712 Main Street | Houston, TX 77002
work phone: 713 - 216 - 5423

--


This email is confidential and subject to important disclaimers and
conditions including on offers for the purchase or sale of
securities, accuracy and completeness of information, viruses,
confidentiality, legal privilege, and legal entity disclaimers,
available at http://www.jpmorgan.com/pages/disclosures/email.  
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question (Poll)

2012-03-14 Thread Arnaud Delobelle
On 14 March 2012 22:15, Prasad, Ramit  wrote:
> Only use 'is' if you are looking for objects like True,
> False, None or something that MUST be exactly the same object.

I've rarely seen valid uses of 'is True' or 'is False'.

-- 
Arnaud
-- 
http://mail.python.org/mailman/listinfo/python-list


RE: Style question (Poll)

2012-03-14 Thread Prasad, Ramit
> >> Which is preferred:
> >>
> >> for value in list:
> >>   if not value is another_value:
> >> value.do_something()
> >> break
> 
> Do you really mean 'is' or '=='?

Let me expound on how 'is' and '==' are very different. It may work 
for some comparisons but often not for others. Certain examples work
because of the Python implementation. 

>>> c = 1
>>> d = 1
>>> c is d # This only works because CPython caches small values.
True
>>> c == d
True
>>> a = 10
>>> b = 10
>>> a is b
False
>>> a == b
True
>>> 10 is 10 
True

'10 is 10' works because the interpreter caches
the number because it is on the same line.


Only use 'is' if you are looking for objects like True,
False, None or something that MUST be exactly the same object.

In general, use '=='.



Ramit


Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology
712 Main Street | Houston, TX 77002
work phone: 713 - 216 - 5423

--

This email is confidential and subject to important disclaimers and
conditions including on offers for the purchase or sale of
securities, accuracy and completeness of information, viruses,
confidentiality, legal privilege, and legal entity disclaimers,
available at http://www.jpmorgan.com/pages/disclosures/email.  
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question (Poll)

2012-03-14 Thread Terry Reedy

On 3/14/2012 4:49 PM, Arnaud Delobelle wrote:

On 14 March 2012 20:37, Croepha  wrote:

Which is preferred:

for value in list:
  if not value is another_value:
value.do_something()
break


Do you really mean 'is' or '=='?

If you mean x is not y, write it that way.
'not x is y' can be misread and misunderstood, depending on whether
the 'is' is true or not.

>>> not 1 is 1
False
>>> not (1 is 1)
False
>>> (not 1) is 1
False

Does not matter how read.

>>> not (1 is 0)
True
>>> (not 1) is 0
False
>>> not 1 is 0
True

Does matter how read.


if list and not list[0] is another_value:
  list[0].do_something()


Or
try:
  value = mylist[0]
  if value is not another_value: value.dosomething
except IndexError:
  pass

I would not do this in this case of index 0, but if the index were a 
complicated expression or expensive function call, making 'if list' an 
inadequate test, I might.



Hard to say, since they don't do the same thing :)

I suspect you meant:

for value in list:
if not value is another_value:
value.do_something()
break

I always feel uncomfortable with this because it's misleading: a loop
that never loops.


I agree. Please do not do this in public ;-).

--
Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question (Poll)

2012-03-14 Thread Arnaud Delobelle
On 14 March 2012 20:37, Croepha  wrote:
> Which is preferred:
>
> for value in list:
>  if not value is another_value:
>    value.do_something()
>    break
>
> --or--
>
> if list and not list[0] is another_value:
>  list[0].do_something()

Hard to say, since they don't do the same thing :)

I suspect you meant:

for value in list:
   if not value is another_value:
   value.do_something()
   break

I always feel uncomfortable with this because it's misleading: a loop
that never loops.

-- 
Arnaud
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: Nicknames for deeply nested objects

2011-02-03 Thread Jean-Michel Pichavant

Gerald Britton wrote:



Nope. it's nothing to do with imports.  It's about objects passed to
methods at run time.  Complicated objects with many levels.  Not about
modules at all.
  


Who is providing these objects ?
- Your code ? => as said before, you can fix your design with a proper 
object model
- 3rd party libraries ? => I'd be curious to know which one, because 
they usually do a good job providing a clean minimal public interface.


However, do not redesign anything to get only shorter names. You can 
easily live with that, the way you're doing it is up to you and 
suggestions have been given. But keep in mind that you should'nt have 
got nested names that long in the first pace, no matter how complicated 
the internal implementation.


JM
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: Nicknames for deeply nested objects

2011-02-03 Thread Jean-Michel Pichavant

Gerald Britton wrote:


however, considering what

"import a.module.that.is.quite.nested as myModule"



Won't work since I get the objects at run time


  
myModule = __import__('whatever.module.imported.at.run.time', globals(), 
locals(), [], -1)


See http://docs.python.org/library/functions.html#__import__

JM


--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: Nicknames for deeply nested objects

2011-01-31 Thread Jean-Michel Pichavant

Gerald Britton wrote:

Hi all,

Today I was thinking about a problem I often encounter.  
[snip]


1. You need to call this thing many times with different arguments, so
you wind up with:

   x = some.deeply.nested.object.method(some.other.deeply.nested.object.value1)
   y = some.deeply.nested.object.method(some.other.deeply.nested.object.value2)
   z = some.deeply.nested.object.method(some.other.deeply.nested.object.value3)
[snip]
--
Gerald Britton
  

This is not solved by style but by design.
You simply don't use too much nested objects. That's a sign of something 
wrong in your overall object model.


Since I do not encounter this problem as often as you are, I guess it is 
a matter of habbits.


however, considering what

"import a.module.that.is.quite.nested as myModule"

is doing, I guess using a local variable to store your nested method is 
just fine.


JM
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: Nicknames for deeply nested objects

2011-01-30 Thread Stephen Hansen
On 1/30/11 1:13 PM, rantingrick wrote:
> On Jan 30, 12:53 pm, Stephen Hansen  wrote:
>> OH MY GOD. How can someone be expected to understand what a function does!
> 
> Yes, and also how decorators word and generators work, and ...
> 
>> Be serious! You can't expect that of them.
> 
> I don't. I don't expect anyone to write 10 lines of obfuscation code
> when just two will suffice. Maybe you should join the perl group as
> they would proud!

Riiight.

"suffice" doesn't mean what you think it means. Generally, if something
suffices -- it actually, you know, ... works.

My four lines of setup can get put into a library and treated as a
recipe if they don't want to get into understanding generators or
decorators: then its two lines to use, and those two lines are exactly
like your two lines except for two little details:

  1. They add a function call to the syntax.
  2. They actually work.

The OP doesn't have to understand decorators or generators if he doesn't
want to: though I encourage him to do so, as they are beautiful and
elegant tools that can very clearly and concisely help solve a lot of
problems.

Now, me? I wouldn't use the recipe, as I originally said in my response.
I'd just use a local variable. But the OP didn't like that, and he
wanted some indenting and whitespace to clearly demarcate where he
intended to use the local. So I gave him a way to do that.

You gave him... uh, what was it again?

Oh, right.

Nothing.

As usual.

-- 

   Stephen Hansen
   ... Also: Ixokai
   ... Mail: me+list/python (AT) ixokai (DOT) io
   ... Blog: http://meh.ixokai.io/



signature.asc
Description: OpenPGP digital signature
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: Nicknames for deeply nested objects

2011-01-30 Thread Steven D'Aprano
On Sun, 30 Jan 2011 12:51:20 -0500, Gerald Britton wrote:

> Hi all,
> 
> Today I was thinking about a problem I often encounter.  Say that I have
> (seems I often do!) a deeply nested object, by which I mean object
> within object with object, etc.
> 
> For example:
> 
>    x =
>    some.deeply.nested.object.method
(some.other.deeply.nested.object.value)
> 
> Well, that's extreme but I've worked with code approaching that level of
> nested-ness.

Then you're probably living in a state of sin, programming-wise, and you 
should stop doing that! You are violating the Law of Demeter. One dot, 
good. Two, acceptable. Three is a code smell. Four is a code reek.

The Law of Demeter (more of a guideline than a law, really) says:

If you want to get your dog to walk, call the dog. Don't talk to its 
legs, it confuses the dog and doesn't get it anywhere.

http://en.wikipedia.org/wiki/Law_of_Demeter

Another analogy: if you have to pay the paperboy for delivering the 
newspaper, you don't let him reach into your pocket, take out your 
wallet, open the wallet, take out whatever money he feels like, and put 
the wallet back.

http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper-
boy/demeter.pdf


Despite my comment above, the Law of Demeter is not *really* a dot-
counting exercise, although that's a handy short-cut for detecting 
potential problems. It can also apply to other data structures. If you've 
every seen C or Pascal code where you have a pointer to a pointer to a 
pointer to a pointer to a pointer to a pointer to some data, you've seen 
a violation.

Consider your example:

some.other.deeply.nested.object.value

This is very tightly coupled code: the caller, who knows about the object 
`some`, needs to know the internal details of not just `some` but also 
`other`, `deeply`, `nested`, and `object`. As a basic principle, this is 
poor design! Which would you rather deal with?

car.start()

car.ignition.turn(key).connect(car.starter(battery), car.spark_plug)

In particular, using temporary variables merely disguises the problem:

temp = some.other
temp = temp.deeply.nested
x = temp.object.value

Even though you never use more than two dots, you still have tight 
coupling. The point of Demeter is not to save dots (they're a renewable 
resource) but to reduce tight coupling.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: Nicknames for deeply nested objects

2011-01-30 Thread Jerry Hill
>
> I don't. I don't expect anyone to write 10 lines of obfuscation code
> when just two will suffice. Maybe you should join the perl group as
> they would proud!


But Stephen's 10 lines of somewhat obscure code actually works, and your two
lines of code doesn't.  I know which one I would prefer.

-- 
Jerry
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: Nicknames for deeply nested objects

2011-01-30 Thread rantingrick
On Jan 30, 12:53 pm, Stephen Hansen  wrote:
> On 1/30/11 10:35 AM, rantingrick wrote:
>
> > Well congratulations Stephen, you win the obfuscation prize of the
> > year!
>
> Yes,
>
> On 1/30/11 10:09 AM, rantingrick wrote:
>
> > Here is how a pythonic local block would look
>
> > with this as localvar:
> >     localvar.do_something()
>
> verses
>
> with my(this) as localvar:
>     localvar.do_something()
>
> Is dreadfully more, er, obfuscated.

Absolutely!

> I mean someone would have to know what the 'my' function does to
> understand what's going on!

Yes, and also how decorators word and generators work, and ...

> OH MY GOD. How can someone be expected to understand what a function does!

Yes, and also how decorators word and generators work, and ...

> Be serious! You can't expect that of them.

I don't. I don't expect anyone to write 10 lines of obfuscation code
when just two will suffice. Maybe you should join the perl group as
they would proud!

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: Nicknames for deeply nested objects

2011-01-30 Thread Ian

On 30/01/2011 17:51, Gerald Britton wrote:

Hi all,

Today I was thinking about a problem I often encounter.  Say that I
have (seems I often do!) a deeply nested object, by which I mean
object within object with object, etc.

For example:

x = some.deeply.nested.object.method(some.other.deeply.nested.object.value)

Well, that's extreme but I've worked with code approaching that level
of nested-ness.  Now, consider two scenarios:

1. You need to call this thing many times with different arguments, so
you wind up with:

x = some.deeply.nested.object.method(some.other.deeply.nested.object.value1)
y = some.deeply.nested.object.method(some.other.deeply.nested.object.value2)
z = some.deeply.nested.object.method(some.other.deeply.nested.object.value3)


Neither.  You should tell. Don't ask if you can avoid it.

Compare...

queen.getButter()

and
queen.dairymaid.alderney.getButter()

see  http://www.timelessteacherstuff.com/readerstheater/KingsBreakfast.pdf

king doesn't care where or how the butter is brought.  Neither should 
your code!


What are you doing with value1, value2 and value3 when you have them 
anyway? Stuffing them 3 levels deep into something else?


Stop writing procedural code, and write object oriented code instead!

If you you make some tell  deeply.nested.object  about 
other.deeply.nested.object it can fetch its own values, but it might be 
better
to have some tell other.deeply.nested.object about deeply.nested.object 
to it can issue the correct commands.


Then you tell some to  do Somthing by writing

  some.takeMeaningfullAction()

and it all happens "under the covers".

Regards

Ian
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: Nicknames for deeply nested objects

2011-01-30 Thread Stephen Hansen
On 1/30/11 10:35 AM, rantingrick wrote:
> Well congratulations Stephen, you win the obfuscation prize of the
> year!

Yes,

On 1/30/11 10:09 AM, rantingrick wrote:
> Here is how a pythonic local block would look
>
> with this as localvar:
> localvar.do_something()

verses

with my(this) as localvar:
localvar.do_something()

Is dreadfully more, er, obfuscated.

I mean someone would have to know what the 'my' function does to
understand what's going on!

OH MY GOD. How can someone be expected to understand what a function does!

Be serious! You can't expect that of them.

-- 

   Stephen Hansen
   ... Also: Ixokai
   ... Mail: me+list/python (AT) ixokai (DOT) io
   ... Blog: http://meh.ixokai.io/



signature.asc
Description: OpenPGP digital signature
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: Nicknames for deeply nested objects

2011-01-30 Thread rantingrick
On Jan 30, 12:23 pm, Stephen Hansen  wrote:

> --- start
> from contextlib import contextmanager
>
> class Item(object): pass
>
> deeply = Item()
> deeply.nested = Item()
> deeply.nested.thing = Item()
>
> @contextmanager
> def my(thing):
>     yield thing
>
> with my(deeply.nested.thing) as o:
>     o.hello = 1
>
> print deeply.nested.thing.hello
> --- end

Well congratulations Stephen, you win the obfuscation prize of the
year!
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: Nicknames for deeply nested objects

2011-01-30 Thread Stephen Hansen
On 1/30/11 9:51 AM, Gerald Britton wrote:
> 1. If you had to choose between approaches 1 and 2, which one would
> you go for, and why?

Neither. Ideally, I'd tweak the API around so the deeply nested
structure isn't something I need to access regularly. But! If you can't
do that, I'd do something like:

--- start
from contextlib import contextmanager

class Item(object): pass

deeply = Item()
deeply.nested = Item()
deeply.nested.thing = Item()

@contextmanager
def my(thing):
yield thing


with my(deeply.nested.thing) as o:
o.hello = 1

print deeply.nested.thing.hello
--- end

That's a dummy context-manager which basically does nothing: it just
"abuses" the context manager protocol to basically make a local variable
and indent its usage. Its really just a run-around and slightly less
efficient to do:

>_o = some.deeply.nested.object
>_o.method(_o.value)

But with the whitespace added on.

Personally, I'd usually just make a local variable and skip any tricks.

-- 

   Stephen Hansen
   ... Also: Ixokai
   ... Mail: me+list/python (AT) ixokai (DOT) io
   ... Blog: http://meh.ixokai.io/



signature.asc
Description: OpenPGP digital signature
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: Nicknames for deeply nested objects

2011-01-30 Thread Roy Smith
In article ,
 Gerald Britton  wrote:

> 1. You need to call this thing many times with different arguments, so
> you wind up with:
> 
>    x = 
> some.deeply.nested.object.method(some.other.deeply.nested.object.value1)
>    y = 
> some.deeply.nested.object.method(some.other.deeply.nested.object.value2)
>    z = 
> some.deeply.nested.object.method(some.other.deeply.nested.object.value3)

I would probably turn that into:

object = some.deeply.nested.object
object.method(object.value1)
object.method(object.value2)
object.method(object.value3)

i.e. make the temporary variable have the exact same name as the last 
component of the deeply nested thing you're trying to refactor.  If the 
scope of use is small and the meaning is obvious from context, sometimes 
I'll shorten the name, i.e.

 obj = some.deeply.nested.object

or even

 o = some.deeply.nested.object

but I tend to avoid doing that.  I'd rather be a little more verbose in 
preference to being a little more cryptic.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question: Nicknames for deeply nested objects

2011-01-30 Thread rantingrick
On Jan 30, 11:51 am, Gerald Britton  wrote:

[...]

> that I might confuse with the first.  To make it look better I might do this:
>
>    _o = some.deeply.nested.object
>    _o.method(_o.value)
>
> which is fine, I suppose.

It is very fine. And you "supposed" correctly!


> Then, putting on my company hat, I remembered that, from VBA, you could do 
> this:
>
>    with some.deeply.nested.object
>        .method(.value)
>    end with
>
> I like the structure of this, since the subordinate block can be
> indented, which makes it stand out.  Also, it avoids temporary
> variables.

Yes it is a good idea! Well forgetting the horrendous VBA syntax this
is. I brought this up many moons back as a feature request: Local
Blocks. Here is how a pythonic local block would look

with this as localvar:
localvar.do_something()


> So, I was thinking of how to get close to this in Python.  I came up
> with two approaches:
>
> 1.
>
>    _o = some.deeply.nested.object
>    if 1:
>        _o.method(_o.value)

bad idea!


> 2.
>
>     for _o in [some.deeply.nested.object]:
>        _o.method(_o.value)

even worse idea!


> I have a couple of questions:
>
> 1. If you had to choose between approaches 1 and 2, which one would
> you go for, and why?

neither! Stick with the original.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question for conditional execution

2010-11-24 Thread Asun Friere
On Nov 25, 7:43 am, Paul Rubin  wrote:
> Gerald Britton  writes:
> >     if v:
> >         f()
>
> > I might, however, think more in a functional-programming direction.
> > Then I might write:
>
> >     v and f()
>
> Python has conditional expressions.  The above would be:
>
>     f() if v else None
>
> using "and" is bug-prone.

Using 'and' is indeed bug-prone when used in combination with 'or' to
achieve a ternary conditional op, as was done the pre PEP308 days, eg
"val = cond and a or b" because of the possibility that 'a' was itself
not true, (thus requiring the ugly 'val = (cond and [a] or [b])[0]').

But no such bug could occur with this particular idiom. What could
possibly go wrong here? :)

That being said, I agree with previous posters that "if cond : fn()"
wins in terms of readability.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question for conditional execution

2010-11-24 Thread Paul Rubin
Gerald Britton  writes:
> if v:
> f()
>
> I might, however, think more in a functional-programming direction.
> Then I might write:
>
> v and f()

Python has conditional expressions.  The above would be:

f() if v else None

using "and" is bug-prone.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question for conditional execution

2010-11-24 Thread Arnaud Delobelle
Gerald Britton  writes:

> Writing in Python gives me the luxury of choosing different paradigms
> for similar operations.  Lately I've been thinking about a minor
> detail that peaked my interest and am curious what others think:
>
> Say that I have some function "f" that I will execute if some variable
> "v" evaluates true.  Using a classical procedural approach, I might
> write:
>
> if v:
> f()
>
> I might, however, think more in a functional-programming direction.
> Then I might write:
>
> v and f()
>
> Interestingly, this second expression compiles smaller (though only by
> a little) in both Python 2.6 and 3.1, which I currently have
> installed.  If I had thousands of such expressions, I could boast
> about a measurable difference but practically speaking, it is not
> significant.
>
> What I _am_ interested in, however, is feedback from a style perspective.
>
> What do the rest of you think about this?
>
> Have you used the second approach and, if so, what was your motivation?
>
> Is there a good/bad reason to choose one over the other?

I would use the if: form every time but it's interesting that the
"JUMP_FORWARD 0" instruction below doesn't get optimised away.

If it did, both forms would be the same compiled lengths.

>>> def g():
... if v: f()
... 
>>> dis.dis(g2)
  2   0 LOAD_GLOBAL  0 (v) 
  3 POP_JUMP_IF_FALSE   16 
  6 LOAD_GLOBAL  1 (f) 
  9 CALL_FUNCTION0 
 12 POP_TOP  
 13 JUMP_FORWARD 0 (to 16) 
>>   16 LOAD_CONST   0 (None) 
 19 RETURN_VALUE 

-- 
Arnaud
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question for conditional execution

2010-11-24 Thread Steven Howe
Both paradigms are in the bash shell. Using a test switch (like -x for 
executiable) mixed with an && or ||.

Example:
[-x /usr/bin/firefox ] || exit

I think it's very clear, to old hands, but not so much for a new or
intermediate users.

It certainly is the 'cleaner' form. Like the C style increment " x++ " 
or the insidious  " x += 4 ". However I often found myself looking for 
places to use "x += 4" instead of just using the clear:

"x = x + 4 ".

Unless there is a significant compiler/executable improvement it just 
there to amuse yourself.


The
if v:
f()

structure is clearer. Which is the only reason to use indents, braces 
and the like. I suppose that's my vote/opinion. Given a choice between 
clean or clear, take clear.


sph


On 11/24/2010 10:46 AM, Gerald Britton wrote:

Writing in Python gives me the luxury of choosing different paradigms
for similar operations.  Lately I've been thinking about a minor
detail that peaked my interest and am curious what others think:

Say that I have some function "f" that I will execute if some variable
"v" evaluates true.  Using a classical procedural approach, I might
write:

 if v:
 f()

I might, however, think more in a functional-programming direction.
Then I might write:

 v and f()

Interestingly, this second expression compiles smaller (though only by
a little) in both Python 2.6 and 3.1, which I currently have
installed.  If I had thousands of such expressions, I could boast
about a measurable difference but practically speaking, it is not
significant.

What I _am_ interested in, however, is feedback from a style perspective.

What do the rest of you think about this?

Have you used the second approach and, if so, what was your motivation?

Is there a good/bad reason to choose one over the other?



--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question for conditional execution

2010-11-24 Thread Ed Leafe
On Nov 24, 2010, at 1:46 PM, Gerald Britton wrote:

> Say that I have some function "f" that I will execute if some variable
> "v" evaluates true.  Using a classical procedural approach, I might
> write:
> 
>if v:
>f()
> 
> I might, however, think more in a functional-programming direction.
> Then I might write:
> 
>v and f()
> 
> Interestingly, this second expression compiles smaller (though only by
> a little) in both Python 2.6 and 3.1, which I currently have
> installed.  If I had thousands of such expressions, I could boast
> about a measurable difference but practically speaking, it is not
> significant.
> 
> What I _am_ interested in, however, is feedback from a style perspective.
> 
> What do the rest of you think about this?

Readability is key. The first is instantly understandable; the second 
only if you are familiar with that particular programming construct. Explicit 
is better than implicit, so I'd go with the first form.


-- Ed Leafe



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Style question for conditional execution

2010-11-24 Thread Ian
On Nov 24, 11:46 am, Gerald Britton  wrote:
> Say that I have some function "f" that I will execute if some variable
> "v" evaluates true.  Using a classical procedural approach, I might
> write:
>
>     if v:
>         f()
>
> I might, however, think more in a functional-programming direction.
> Then I might write:
>
>     v and f()

The idea that "if" is inherently procedural is mistaken.  Functional
programming emphasizes the use of functions (in the mathematical
sense) over changes in state.  Assuming that f has no side effects,
either of the above could equally be viewed as functional.

(Of course, the fact that the return value is simply discarded in both
of the above cases suggests that f *does* have side effects, in which
case neither of the above should be viewed as functional.)

That said, the 'if' version is clearer, so I would nearly always go
with that.  The rare exception would be if I were genuinely interested
in capturing the value of "v" if it evaluated false.  I can't remember
the last time that was the case.

Cheers,
Ian
-- 
http://mail.python.org/mailman/listinfo/python-list


RE: Style question - defining immutable class data members

2009-03-31 Thread John Posner
I said:

 >> > My intent was to fix an obvious omission: a special case 
 >> was discussed in
 >> > the "Augmented assignment statements" section, but an 
 >> almost-identical
 >> > special case was omitted from the "Assignment statements" section.

After finally getting registered at bugs.python.org (as described in another
thread), I submitted  my suggested change to the Python documentation. It's
issue 5621.

-John





E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.12080
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-27 Thread Steve Holden
John Posner wrote:
> [snip]
>  >> > If the object is a class instance and the attribute reference
> occurs
>  >> > on both sides of the assignment operator; for example::
>  >> > 
>  >> > self.x = self.x + 1
>  >> >
>  >> > ... in the RHS expression, ``self.x`` is evaluated with 
>  >> > ``getattr()``, which can access either an instance attribute or
> (if 
>  >> > no instance attribute exists) a class attribute. The LHS target 
>  >> > ``self.x`` is assigned with ``setattr()``, which *always* accesses
> 
>  >> > an instance attribute, creating it if necessary. Thus, the two 
> 
> Steve Holden said: 
> 
>  >> Is this true in the case of read-write properties? This 
>  >> seems a little
>  >> simplistic for what's actually a pretty complex piece of logic.
> 
> It's not true for the read-write property example in the official property()
> function description:
> 
> class C(object):
> def __init__(self):
> self._x = None
> 
> def getx(self):
> return self._x
> def setx(self, value):
> self._x = value
> def delx(self):
> del self._x
> x = property(getx, setx, delx, "I'm the 'x' property.")
> 
> 
> But it *is* true if you revise this class definition to follow the pattern
> under discussion: a class attribute provides the "initial value" of an
> instance attribute:
> 
> class C(object):
> _x = 0
> 
> def __init__(self):
> pass
> def getx(self):
> return self._x
> def setx(self, value):
> self._x = value
> x = property(getx, setx)
> 
> 
> My intent was to fix an obvious omission: a special case was discussed in
> the "Augmented assignment statements" section, but an almost-identical
> special case was omitted from the "Assignment statements" section.
> 
> Neither section currently mentions property attributes. Do you think both
> sections should be changed to cover property attributes? Or maybe it would
> be simpler just to revise my first sentence:
> 
>   from: If the object is a class instance
> to: If the object is a (non-property) class instance
> 
That amendment would probably be least confusing to new readers, though
it would help when in hypermedia to link "property" to some discussion
of properties as they apply on the various Python versions.

regards
 Steve
-- 
Steve Holden   +1 571 484 6266   +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/
Want to know? Come to PyCon - soon! http://us.pycon.org/

--
http://mail.python.org/mailman/listinfo/python-list


RE: Style question - defining immutable class data members

2009-03-26 Thread John Posner
[snip]
 >> > If the object is a class instance and the attribute reference
occurs
 >> > on both sides of the assignment operator; for example::
 >> > 
 >> > self.x = self.x + 1
 >> >
 >> > ... in the RHS expression, ``self.x`` is evaluated with 
 >> > ``getattr()``, which can access either an instance attribute or
(if 
 >> > no instance attribute exists) a class attribute. The LHS target 
 >> > ``self.x`` is assigned with ``setattr()``, which *always* accesses

 >> > an instance attribute, creating it if necessary. Thus, the two 

Steve Holden said: 

 >> Is this true in the case of read-write properties? This 
 >> seems a little
 >> simplistic for what's actually a pretty complex piece of logic.

It's not true for the read-write property example in the official property()
function description:

class C(object):
def __init__(self):
self._x = None

def getx(self):
return self._x
def setx(self, value):
self._x = value
def delx(self):
del self._x
x = property(getx, setx, delx, "I'm the 'x' property.")


But it *is* true if you revise this class definition to follow the pattern
under discussion: a class attribute provides the "initial value" of an
instance attribute:

class C(object):
_x = 0

def __init__(self):
pass
def getx(self):
return self._x
def setx(self, value):
self._x = value
x = property(getx, setx)


My intent was to fix an obvious omission: a special case was discussed in
the "Augmented assignment statements" section, but an almost-identical
special case was omitted from the "Assignment statements" section.

Neither section currently mentions property attributes. Do you think both
sections should be changed to cover property attributes? Or maybe it would
be simpler just to revise my first sentence:

  from: If the object is a class instance
to: If the object is a (non-property) class instance





E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.12050
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-25 Thread Steve Holden
John Posner wrote:
> On Mon Mar 16 03:42:42, I said:
> 
>> RTFM, in section "Augmented assignment statements" of python301.chm:
>>
>> ---
>> For targets which are attribute references, the initial value is retrieved
> 
>> with a getattr() and the result is assigned with a setattr(). Notice that
> the 
>> two methods do not necessarily refer to the same variable. When getattr() 
>> refers to a class variable, setattr() still writes to an instance
> variable. 
>> For example:
>>
>> class A:
>> x = 3# class variable
>> a = A()
>> a.x += 1 # writes a.x as 4 leaving A.x as 3
>> ---
>>
>> So, this case is closed ... almost. I believe a similar explanation, with
> a 
>> similar example, should appear in the preceding/parent section,
> "Assignment 
>> statements". Here's my proposed example:
>>
>>class A:
>>x = 3 # class variable
>>a = A()
>>a.x = a.x + 1 # a.x on RHS gets value of class variable (3)
>>  # a.x on LHS creates instance variable with
>>value of RHS expression (4)
> 
> Following is a draft of my proposed addendum to the "Assignment statements"
> section of the Python documentation (for both Python 2 and Python 3). I've
> included reStructured Text markup. The first paragraph is what's already in
> the documentation. Everything else is mine:
> 
>   * If the target is an attribute reference: The primary expression in 
> the reference is evaluated. It should yield an object with 
> assignable attributes; if this is not the case, TypeError is raised. 
> That object is then asked to assign the assigned object to the given 
> attribute; if it cannot perform the assignment, it raises an 
> exception (usually but not necessarily AttributeError).
> 
> If the object is a class instance and the attribute reference occurs
> on both sides of the assignment operator; for example::
> 
> self.x = self.x + 1
> 
> ... in the RHS expression, ``self.x`` is evaluated with 
> ``getattr()``, which can access either an instance attribute or (if 
> no instance attribute exists) a class attribute. The LHS target 
> ``self.x`` is assigned with ``setattr()``, which *always* accesses 
> an instance attribute, creating it if necessary. Thus, the two 

Is this true in the case of read-write properties? This seems a little
simplistic for what's actually a pretty complex piece of logic.

> occurrences of ``self.x`` do not necessarily refer to the same 
> variable. If the RHS expression refers to a class attribute, the LHS 
> creates a new instance attribute as the target of the assignment.
> 
> See section "Augmented assignment statements" for a similar note on 
> attribute references. 
> 
> 
> If anyone would like to suggest changes to this write-up, have at it. I plan
> to submit a SourceForge issue within a day or so.
> 
> (BTW, I searched through the existing issues, to see if it has already been
> reported. AFAIK, it hasn't. But #4246 is a cousin, referencing
> UnboundLocalError exceptions.
> 
regards
 Steve
-- 
Steve Holden   +1 571 484 6266   +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/
Want to know? Come to PyCon - soon! http://us.pycon.org/

--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-25 Thread John Posner
On Mon Mar 16 03:42:42, I said:

> RTFM, in section "Augmented assignment statements" of python301.chm:
> 
> ---
> For targets which are attribute references, the initial value is retrieved

> with a getattr() and the result is assigned with a setattr(). Notice that
the 
> two methods do not necessarily refer to the same variable. When getattr() 
> refers to a class variable, setattr() still writes to an instance
variable. 
> For example:
> 
> class A:
> x = 3# class variable
> a = A()
> a.x += 1 # writes a.x as 4 leaving A.x as 3
> ---
> 
> So, this case is closed ... almost. I believe a similar explanation, with
a 
> similar example, should appear in the preceding/parent section,
"Assignment 
> statements". Here's my proposed example:
> 
>class A:
>x = 3 # class variable
>a = A()
>a.x = a.x + 1 # a.x on RHS gets value of class variable (3)
>  # a.x on LHS creates instance variable with
>value of RHS expression (4)

Following is a draft of my proposed addendum to the "Assignment statements"
section of the Python documentation (for both Python 2 and Python 3). I've
included reStructured Text markup. The first paragraph is what's already in
the documentation. Everything else is mine:

  * If the target is an attribute reference: The primary expression in 
the reference is evaluated. It should yield an object with 
assignable attributes; if this is not the case, TypeError is raised. 
That object is then asked to assign the assigned object to the given 
attribute; if it cannot perform the assignment, it raises an 
exception (usually but not necessarily AttributeError).

If the object is a class instance and the attribute reference occurs
on both sides of the assignment operator; for example::

self.x = self.x + 1

... in the RHS expression, ``self.x`` is evaluated with 
``getattr()``, which can access either an instance attribute or (if 
no instance attribute exists) a class attribute. The LHS target 
``self.x`` is assigned with ``setattr()``, which *always* accesses 
an instance attribute, creating it if necessary. Thus, the two 
occurrences of ``self.x`` do not necessarily refer to the same 
variable. If the RHS expression refers to a class attribute, the LHS 
creates a new instance attribute as the target of the assignment.

See section "Augmented assignment statements" for a similar note on 
attribute references. 


If anyone would like to suggest changes to this write-up, have at it. I plan
to submit a SourceForge issue within a day or so.

(BTW, I searched through the existing issues, to see if it has already been
reported. AFAIK, it hasn't. But #4246 is a cousin, referencing
UnboundLocalError exceptions.

-John





E-mail message checked by Spyware Doctor (6.0.0.386)
Database version: 5.12040
http://www.pctools.com/en/spyware-doctor-antivirus/
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-24 Thread Aahz
In article ,
Maxim Khitrov   wrote:
>
>Very simple question on the preferred coding style. I frequently write
>classes that have some data members initialized to immutable values.
>For example:
>
>class Test(object):
>def __init__(self):
>self.some_value = 0
>self.another_value = None
>
>Similar effect can be achieved by defining some_value and
>another_value for the entire class, like so:
>
>class Test(object):
>some_value = 0
>another_value = None
>
>The advantage of doing this is that the assignments are evaluated once
>and thus the creation of that class is a bit faster. Access is still
>performed through self.some_value and self.another_value. Is there a
>reason to prefer the first style over the second?

Well, as you can see from reading this whole thread, it can be the source
of some confusion.  Nevertheless, I personally sometimes use the style of
initializing at the class level.  I think it's probably worth creating a
style guide entry for this issue if you're using Python for your
employer.
-- 
Aahz (a...@pythoncraft.com)   <*> http://www.pythoncraft.com/

"At Resolver we've found it useful to short-circuit any doubt and just
refer to comments in code as 'lies'. :-)"
--Michael Foord paraphrases Christian Muirhead on python-dev, 2009-3-22
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-16 Thread Rhodri James
On Mon, 16 Mar 2009 09:31:59 -, Aaron Brady   
wrote:

[snippety snip]

Otherwise, either /1, every instance has its own entries for class
functions, and subsequent changes to the class don't affect existing
instances, or /2, every method call is of the form x.__class__.foo
( ).  They're both bad.  (...unless that's a false dilemma.)


I must admit I was envisaging a horribly inefficient (in space terms)
version of (1) in which the instance entries were binding stubs that
referenced the class entries, but that still falls over when new
methods get dynamically added to the class.  I blame having two hours
of sleep in three days for this particular bit of dimness, sorry.


P.S.  Do you pronounce 'wildebeeste' like 'vildebeeste'?


No, with a "w" not a "v".  It's just one of those titles that
stick with you no matter what you do.

--
Rhodri James *-* Wildebeeste Herder to the Masses
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-16 Thread Aaron Brady
On Mar 15, 9:54 pm, "Rhodri James" 
wrote:
> On Sun, 15 Mar 2009 23:26:04 -, Aaron Brady   
> wrote:
>
>
>
>
>
> > On Mar 15, 1:50 pm, "Rhodri James" 
> > wrote:
> >> On Sun, 15 Mar 2009 17:55:25 -, Aaron Brady   
> >> wrote:
>
> >> > On Mar 15, 12:39 pm, John Posner  wrote:
> >> >> (My apologies if the thread has already covered this.) I believe I  
> >> >> understand the WHAT in this situation, but I don't understand the >>  
> >> WHY  
> [snip]
> >> > Yes.  If you access an attribute, you want the search to go like this:
>
> >> > - check instance for attribute
> >> > - check class for attribute
> >> > - check base classes for attribute
>
> >> But do you, though?  The only occasion I can think of that I'd want
> >> the search to go past the instance is this "auto-initialisation",
> >> and frankly I'd rather do that in an __init__ anyway.  Perhaps
> >> static methods or class methods work that way, I don't know how
> >> the innards of the interpreter handle that.
>
> > As Bruno stated, yes, for resolving 'self.method', and other
> > descriptors.  You acknowledge that 'foo.jam' would need to identify
> > itself as coming from an instance, class, or base, since the only
> > entries in 'foo's dictionary are those attributes which are particular
> > to 'foo'.
>
> No, I don't acknowledge that.  (Note that John's original question
> was *WHY*, and you effectively gave him a *HOW* answer by asserting
> that it's what he wants.  I'm playing Devil's Advocate to an extent.)

Very valid.  Evidently I thought that the 'how' would justify it.
However, a *WHAT* in this case is pretty close to a 'why'.

You can access instance attributes and class attributes with the same
syntax.  It has the advantage that you can mix two statements into
one:

attr= x.attr
<>
if 'attr' in x.__dict__:
attr= x.__dict__[ 'attr' ]
else:
attr= x.__class__.__dict__[ 'attr' ]

Otherwise, either /1, every instance has its own entries for class
functions, and subsequent changes to the class don't affect existing
instances, or /2, every method call is of the form x.__class__.foo
( ).  They're both bad.  (...unless that's a false dilemma.)

> "self.method" is not the same object as "Class.method"; one's bound
> and the other isn't, for starters.  It's therefore by no means
> obvious that method lookup isn't being done via the instance's
> dictionary.

No.  What makes it obvious is that subsequent changes to the class
affect existing instances.

> After all, some kind of binding has to be done at
> instance creation time.  If you're telling me that it's time-
> efficient (or at least space-efficient and not horribly time-
> inefficient) to use the class dictionary and magically know to
> wrapper the call, then we've that makes things different and
> gives us a reason for wanting that search order.

It's more space efficient.  However, the additional time involved in
the 'instance-first-class-second' search, plus the process of creating
the bound method (once per access, by the way, currently), can
counterweigh or outweigh that.

> It's the same story with descriptors; in fact they mask rather
> more of the detail of what they're doing and look at first glance
> more tightly bound to the instance than the class.  Further steps
> get you to the same "why" answer, but they are further steps.

No, I did leave some of the steps to the analysis tacit.  My mistake.

> > Class attributes are grouped together in the class dictionary,
> > instance attributes are grouped together in the instance dictionary,
> > and instances need to see both.
>
> True, but they don't need to see both with instance attribute
> syntax.  That they can is what we're trying to justify here.

As above, the alternatives (explicit class access and redundant
instance membership) are bad.

> > If you have a counter-proposal, either for a wishlist for behavior, or
> > a way of arranging its implementation, I for one would entertain it,
> > even on the c-l-python newsgroup, and even though it wouldn't have
> > much of a chance of making it in to Python.
>
> Nope, no proposal.  Mildly considering one, but I thought I'd try
> understanding why what happens is considered a good thing before I
> let my hare-brainedness off the leash.

I know... that was just a tactic to get you to do the work of
enumerating the alternatives.  Bah.

> > As a side note, this argument of 'whose methods am I seeing?' has an
> > inconvenient artifact: the behavior of 'foo.method'.  'foo.method'
> > needs to refer to an instance method, due to not needing the 'self'
> > attribute respecified; while 'foo.__class__.method' needs to refer to
> > a plain function.  Python's solution is a skeleton type, that just
> > redirects 'foo.method( )' to an append of the arguments plus call.
>
> As I said, this inconvenient artefact is exactly why I didn't think
> assuming instance method lookup happened via the *class* dictionary
> was safe!

It's not.  If you assign a function to an instance attribute, the

Re: Style question - defining immutable class data members

2009-03-15 Thread Gary Herron

John Posner wrote:

Matthew Woodcraft said:

  

I doubt it's because anyone particularly wanted this
behaviour; it just
falls out of the way '+=' is defined.

At the point where 'inst.x += 1' is compiled,
Python doesn't know
whether 'inst.x' is going to turn out to be a class
attribute or an
instance attribute or a property. So really the only thing
it can do is
generate code to read inst.x in the usual way and then
assign to inst.x
in the usual way (where 'the usual way' for CPython
is LOAD_ATTR and
STORE_ATTR).



That sounds reasonable to me.


Matthew Woodcraft also said:

  

Is there any actual advantage to self.attribute picking up
Class.attribute instead of raising a NameError?
  


  

You use that any time you call an ordinary method using syntax like
'self.foo()'.



Yes, but that's performing a read (and call) operation on an attribute. My 
question concerned itself with potential confusion when you perform a write 
operation on an attribute.


Bruno Desthuilliers said:

  

My question is ... WHY does the interpreter  silently create the
instance attribute at this point,
  


  

Becaause that's how you create instance attributes in Python. Why do you
think 'self' - that is, a reference to some object - is mandatory in
"methods" (really, functions) arguments list ?



  

Or do you mean that the existence of a synonym class attribute should be
checked on each instance variable assignement ? This would probably be a
big performance hit, ...



Yes, Bruno, I'm persuaded by this argument. Ideally, I'd like the interpreter 
to prevent the programmer from shooting him/herself in the foot, but it's not 
worth the performance hit.

  

and it would make per-instance method overloading
impossible (remember that OOP is about objects, not classes).



Yes again. While I was writing the above comment ("write operation on an 
attribute"), it *did* cross my mind that you might want to write self.attribute, 
even if it names a method, not a data-item.


Summary: I no longer suspect that "Python is broken". I *do* think that there's 
a situation that is potentially quite confusing:

 * In the statement "self.x = self.x + 1", the two "self.x" names can sometimes 
refer to different objects.

 * Even worse, in the equivalent statement "self.x += 1", the single name 
"self.x" can sometimes refer to two different objects!

I think this situation should be handled in documentation. (I'm a tech writer 
in my day job ... oh wait, I forgot ... I got laid off from my day job in 
December.) I'll look into what the standard Python doc set says on this matter.
  


What's broken here is trying to have a class variable and an instance 
variable of the same name and expecting Python to get it right. 

Both of these problems become non-issues if you follow the "best 
practice" for defining instance variables: 

That is, set instance variables to their initial value in the __init__ 
method.And if you need a class default value, name it differently:


For example:

class C:
 default_x = 123

 def __init__(self):
   self.x = self.default_x

 def inc(self):
   self.x += 1 // behaves as expected

Then self.x or inst=C() and inst.x will always refer to a instance 
variable, the code is clear,  and no confusion ensues.




Gary Herron






-John

--
http://mail.python.org/mailman/listinfo/python-list
  


--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread Gary Herron

John Posner wrote:

(My apologies if the thread has already covered this.) I believe I understand 
the WHAT in this situation, but I don't understand the WHY ...

Given this class definition:

  class Cls(object):
  x = 345

... I observe the following, using IDLE 2.6.1:

  

inst = Cls()
Cls.x is inst.x


True

  

Cls.x += 1
Cls.x is inst.x


True

  

inst.x += 1
Cls.x is inst.x


False

My question is ... WHY does the interpreter silently create the instance attribute at 
this point, causing a "surprising decoupling" from the class attribute? WHY 
doesn't the interpreter behave as it would with a simple, non-instance variable:

  > python
  Python 2.6.1 ...
  Type "help", "copyright", "credits" or "license" for more information.

  >>> x += 1
  Traceback (most recent call last):
File "", line 1, in 
  NameError: name 'x' is not defined

Is there a beneficial effect of silently creating the instance attribute, which outweighs 
the detrimental effects: (1) inconsistency, (2) the "surprising" decoupling?
  


I wouldn't call it "silently" because "inst.x = ..." is quite explicit 
about "x" being an attribute of "inst".  The rules for creating a 
variable are simple and very consistent.


Each of
 Cls.x = ...
 inst.x = ...
 x = ...
will create a variable (if it does not already exist) in a class, 
instance or local name space respectively. 

Retrieving a value is more complex as Python may look through several 
namespaces in succession to find a value:  (For example, inst.x will 
check the instance , then the class ...)


The problem here is that
 inst.x += 1
is really
 inst.x = inst.x+1
which according to those rules, (if inst.x is not yet defined)
has both an instance and a class reference in the same statement.

After that, x.inst is defined in the instance, so both sides refer to that.



Gary Herron





Tx,
John


--
http://mail.python.org/mailman/listinfo/python-list
  


--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread Tim Wintle
On Mon, 2009-03-16 at 04:02 +, Tim Wintle wrote:
> On Sun, 2009-03-15 at 10:39 -0700, John Posner wrote:

Doh, reply out of thread there - I meant to reply to Rhodi's comment
further down.
> Is there any actual advantage to self.attribute picking up
> Class.attribute instead of raising a NameError?


--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread Tim Wintle
On Sun, 2009-03-15 at 10:39 -0700, John Posner wrote:
> (My apologies if the thread has already covered this.) I believe I understand 
> the WHAT in this situation, but I don't understand the WHY ...

> Is there a beneficial effect of silently creating the instance attribute, 
> which outweighs the detrimental effects: (1) inconsistency, (2) the 
> "surprising" decoupling?

>From an end-user point of view (rather than the point of accessing class
methods others mentioned), here are two more reasons:

1) To save memory - there's only one object stored, where an instance
variable will require the same memory every instance (normally)


2) referencing Zope objects (although any persistent object storage will
have the same argument):

(Zope is a web framework that stores data as instances of python classes
in a persistent database.)

let's say you have the class (missing all the boilerplate)

{{{
class ZMyUser():
def __init__(self):
self.lookuplanguage = {\
"EN": "English"
}
self.language = "EN"

def get_friendly_name(self):
return self.lookuplanguage.get(self.language,"--")
}}}

And you create loads of these objects. But then you want to add French
as an option. How do you do that? All the objects have already been
created, so you could either: 

 * Run through every object in the database one by one and update the
dict as a one-off task (potentially taking a very long time as you force
the computer to pull the entire database off disk)

 * Have written  lookuplanguage as a class property, so re-initialising
the class will update the definition without any extra overhead.




--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread Rhodri James
On Sun, 15 Mar 2009 23:26:04 -, Aaron Brady   
wrote:



On Mar 15, 1:50 pm, "Rhodri James" 
wrote:

On Sun, 15 Mar 2009 17:55:25 -, Aaron Brady   
wrote:

> On Mar 15, 12:39 pm, John Posner  wrote:
>> (My apologies if the thread has already covered this.) I believe I  
>> understand the WHAT in this situation, but I don't understand the >>  
WHY  

[snip]

> Yes.  If you access an attribute, you want the search to go like this:

> - check instance for attribute
> - check class for attribute
> - check base classes for attribute

But do you, though?  The only occasion I can think of that I'd want
the search to go past the instance is this "auto-initialisation",
and frankly I'd rather do that in an __init__ anyway.  Perhaps
static methods or class methods work that way, I don't know how
the innards of the interpreter handle that.


As Bruno stated, yes, for resolving 'self.method', and other
descriptors.  You acknowledge that 'foo.jam' would need to identify
itself as coming from an instance, class, or base, since the only
entries in 'foo's dictionary are those attributes which are particular
to 'foo'.


No, I don't acknowledge that.  (Note that John's original question
was *WHY*, and you effectively gave him a *HOW* answer by asserting
that it's what he wants.  I'm playing Devil's Advocate to an extent.)

"self.method" is not the same object as "Class.method"; one's bound
and the other isn't, for starters.  It's therefore by no means
obvious that method lookup isn't being done via the instance's
dictionary.  After all, some kind of binding has to be done at
instance creation time.  If you're telling me that it's time-
efficient (or at least space-efficient and not horribly time-
inefficient) to use the class dictionary and magically know to
wrapper the call, then we've that makes things different and
gives us a reason for wanting that search order.

It's the same story with descriptors; in fact they mask rather
more of the detail of what they're doing and look at first glance
more tightly bound to the instance than the class.  Further steps
get you to the same "why" answer, but they are further steps.


Class attributes are grouped together in the class dictionary,
instance attributes are grouped together in the instance dictionary,
and instances need to see both.


True, but they don't need to see both with instance attribute
syntax.  That they can is what we're trying to justify here.


If you have a counter-proposal, either for a wishlist for behavior, or
a way of arranging its implementation, I for one would entertain it,
even on the c-l-python newsgroup, and even though it wouldn't have
much of a chance of making it in to Python.


Nope, no proposal.  Mildly considering one, but I thought I'd try
understanding why what happens is considered a good thing before I
let my hare-brainedness off the leash.


As a side note, this argument of 'whose methods am I seeing?' has an
inconvenient artifact: the behavior of 'foo.method'.  'foo.method'
needs to refer to an instance method, due to not needing the 'self'
attribute respecified; while 'foo.__class__.method' needs to refer to
a plain function.  Python's solution is a skeleton type, that just
redirects 'foo.method( )' to an append of the arguments plus call.


As I said, this inconvenient artefact is exactly why I didn't think
assuming instance method lookup happened via the *class* dictionary
was safe!


 Actually what I want is for
the attribute to be stored where I told it, which could well be in
the class.  If the attribute is specified as "self.attribute", then
yes, put it in the instance.


The way C++ works is by allocating storage for the data and method
pointers in a class.

class X {
int foo;
char jam[ 12 ];
int foojam( int y, int z ) { ...; }
};

X requires 20 bytes: 4 for 'foo', 12 for 'jam', and 4 for 'foojam'...
under a 32-bit target.  (The 4 for 'foojam' come from a virtual
function table, for polymorphic objects er, technically.)


I'm sorry, I'm utterly baffled.  Why is this relevant to my bit
of pedantry?


You get what you want: attributes are stored where you tell them.  But
where are they read from?


No, *why*.  These questions aren't about what the search order
is, they're about why there is a search order.

--
Rhodri James *-* Wildebeeste Herder to the Masses
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread John Posner

Earlier, I said:

> I'll look into what the standard Python doc set says on this
> matter.
> 

RTFM, in section "Augmented assignment statements" of python301.chm:

---
For targets which are attribute references, the initial value is retrieved with 
a getattr() and the result is assigned with a setattr(). Notice that the two 
methods do not necessarily refer to the same variable. When getattr() refers to 
a class variable, setattr() still writes to an instance variable. For example:

class A:
x = 3# class variable
a = A()
a.x += 1 # writes a.x as 4 leaving A.x as 3
---

So, this case is closed ... almost. I believe a similar explanation, with a 
similar example, should appear in the preceding/parent section, "Assignment 
statements". Here's my proposed example:

   class A:
   x = 3 # class variable
   a = A()
   a.x = a.x + 1 # a.x on RHS gets value of class variable (3)
 # a.x on LHS creates instance variable with
   value of RHS expression (4)

Others' thoughts on this?

-John

--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread R. David Murray
John Posner  wrote:
> Summary: I no longer suspect that "Python is broken". I *do* think that
> there's a situation that is potentially quite confusing:
> 
>  * In the statement "self.x = self.x + 1", the two "self.x" names can
>  sometimes refer to different objects.

But this is fundamental to Python.  The name (or slot, in the case of say
a slice assignment) on the left hand side is being given a new binding
by the assignment statement.  So whatever object the 'self.x' on the
left hand side may have pointed to before the statement is executed is
irrelevant (if we ignore '+=' and kin).  That is the essence of assignment
in Python.  If you are surprised by this, then you should probably study
up a bit on the way namespaces work in Python.

What I think you meant is that even though both are represented by the
same token sequence in the source ('self.x'), the two 'x's are actually
located in two different namespaces.  The one on the left hand side of
the assignment is local to the instance, while the one on the right hand
side can cascade upward to the class namespace and resolve to an object
from there.

>  * Even worse, in the equivalent statement "self.x += 1", the single name
>  "self.x" can sometimes refer to two different objects!

Now on this one I'll agree with you about the "worse" part.  Consider:

>>> class A(object):
... x = [1]
... def f(self):
... self.x = self.x + [2]
... print self.x
... 
>>> 
>>> m = A()
>>> m.f()
[1, 2]
>>> A.x
[1]
>>> class B(object):
... x = [1]
... def g(self):
... self.x += [2]
... print self.x
... 
>>> n = B()
>>> n.g()
[1, 2]
>>> B.x
[1, 2]

I'm inclined to call that a problem, myself, even though I understand
why it happens (+= mutates the object pointed to by the class variable
'x', and _then_ the instance variable 'x' is created and pointed at the
same object.  Whereas in the '+' case, a new list is created and the new
'x' instance variable is pointed at that new list.)

There is a somewhat analogous situation with variables in the local scope of
a function and global variables in the module.   For example, we might have:

>>> x = 1
>>> def f():
... print x
... 
>>> f()
1

So, when 'x' isn't found locally, the value gets picked up from the global
namespace.  The difference from the class/instance case is when we try
to assign to it:

>>> def g():
... x = x + 1
... 
>>> g()
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 2, in g
UnboundLocalError: local variable 'x' referenced before assignment
>>> x = []
>>> def g():
... x += [1]
... 
>>> g()
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 2, in g
UnboundLocalError: local variable 'x' referenced before assignment

So in this case Python is warning us about the namespace difference.

Why are the two cases handled differently?  To tell you the truth, I'm
not sure.  I've been programming in Python for years and it just seems
to make sense to me to do it that way.  It does allow you to use class
variables as default values for instance variables, as long as you are
careful when using mutable objects.  But you could argue that it should
behave in a way analogous to local/global.  It would be interesting to
see that argument laid out in full, with all the consequences it would
entail examined.

> I think this situation should be handled in documentation. (I'm a tech writer
> in my day job ... oh wait, I forgot ... I got laid off from my day job in
> December.) I'll look into what the standard Python doc set says on this
> matter.

Doc patches are always welcome, and from what I hear easier to get
accepted than code patches ;)

--
R. David Murray   http://www.bitdance.com


--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread Aaron Brady
On Mar 15, 1:50 pm, "Rhodri James" 
wrote:
> On Sun, 15 Mar 2009 17:55:25 -, Aaron Brady   
> wrote:
>
> > On Mar 15, 12:39 pm, John Posner  wrote:
> >> (My apologies if the thread has already covered this.) I believe I  
> >> understand the WHAT in this situation, but I don't understand the WHY  
> >> ...
>
> [snip]
>
>
>
> >> My question is ... WHY does the interpreter silently create the  
> >> instance attribute at this point, causing a "surprising decoupling"  
> >> from the class attribute? WHY doesn't the interpreter behave as it  
> >> would with a simple, non-instance variable:
>
> >>   > python
> >>   Python 2.6.1 ...
> >>   Type "help", "copyright", "credits" or "license" for more information.
>
> >>   >>> x += 1
> >>   Traceback (most recent call last):
> >>     File "", line 1, in 
> >>   NameError: name 'x' is not defined
>
> >> Is there a beneficial effect of silently creating the instance  
> >> attribute, which outweighs the detrimental effects: (1) inconsistency,  
> >> (2) the "surprising" decoupling?
>
> > Yes.  If you access an attribute, you want the search to go like this:
>
> > - check instance for attribute
> > - check class for attribute
> > - check base classes for attribute
>
> But do you, though?  The only occasion I can think of that I'd want
> the search to go past the instance is this "auto-initialisation",
> and frankly I'd rather do that in an __init__ anyway.  Perhaps
> static methods or class methods work that way, I don't know how
> the innards of the interpreter handle that.

As Bruno stated, yes, for resolving 'self.method', and other
descriptors.  You acknowledge that 'foo.jam' would need to identify
itself as coming from an instance, class, or base, since the only
entries in 'foo's dictionary are those attributes which are particular
to 'foo'.  Others, such as the entries in 'foo's class, are stored in
a different dictionary.  Changes to that class's dictionary are
visible to all 'foo' instances (as desired), as well that as 'foo'
isn't clogged by copies of entries for all of its class's functions.

Class attributes are grouped together in the class dictionary,
instance attributes are grouped together in the instance dictionary,
and instances need to see both.

If you have a counter-proposal, either for a wishlist for behavior, or
a way of arranging its implementation, I for one would entertain it,
even on the c-l-python newsgroup, and even though it wouldn't have
much of a chance of making it in to Python.

As a side note, this argument of 'whose methods am I seeing?' has an
inconvenient artifact: the behavior of 'foo.method'.  'foo.method'
needs to refer to an instance method, due to not needing the 'self'
attribute respecified; while 'foo.__class__.method' needs to refer to
a plain function.  Python's solution is a skeleton type, that just
redirects 'foo.method( )' to an append of the arguments plus call.

> Is there any actual advantage to self.attribute picking up
> Class.attribute instead of raising a NameError?
>
> > If you write an attribute, you want it stored in the attribute, not
>
>                                                         ^
>
> > the class or base classes.
>
> I think you meant "instance" there :-)

Syntax error line 4!  Gasp!  All hands to battle stations.

> Actually what I want is for
> the attribute to be stored where I told it, which could well be in
> the class.  If the attribute is specified as "self.attribute", then
> yes, put it in the instance.

The way C++ works is by allocating storage for the data and method
pointers in a class.

class X {
int foo;
char jam[ 12 ];
int foojam( int y, int z ) { ...; }
};

X requires 20 bytes: 4 for 'foo', 12 for 'jam', and 4 for 'foojam'...
under a 32-bit target.  (The 4 for 'foojam' come from a virtual
function table, for polymorphic objects er, technically.)

Python can't and won't do that, because you want attributes to be able
to join instances over time.

You get what you want: attributes are stored where you tell them.  But
where are they read from?

>
> --
> Rhodri James *-* Wildebeeste Herder to the Masses

--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread John Posner

Matthew Woodcraft said:

> I doubt it's because anyone particularly wanted this
> behaviour; it just
> falls out of the way '+=' is defined.
> 
> At the point where 'inst.x += 1' is compiled,
> Python doesn't know
> whether 'inst.x' is going to turn out to be a class
> attribute or an
> instance attribute or a property. So really the only thing
> it can do is
> generate code to read inst.x in the usual way and then
> assign to inst.x
> in the usual way (where 'the usual way' for CPython
> is LOAD_ATTR and
> STORE_ATTR).

That sounds reasonable to me.


Matthew Woodcraft also said:

>> Is there any actual advantage to self.attribute picking up
>> Class.attribute instead of raising a NameError?

> You use that any time you call an ordinary method using syntax like
> 'self.foo()'.

Yes, but that's performing a read (and call) operation on an attribute. My 
question concerned itself with potential confusion when you perform a write 
operation on an attribute.


Bruno Desthuilliers said:

>> My question is ... WHY does the interpreter  silently create the
>> instance attribute at this point,

> Becaause that's how you create instance attributes in Python. Why do you
> think 'self' - that is, a reference to some object - is mandatory in
> "methods" (really, functions) arguments list ?

> Or do you mean that the existence of a synonym class attribute should be
> checked on each instance variable assignement ? This would probably be a
> big performance hit, ...

Yes, Bruno, I'm persuaded by this argument. Ideally, I'd like the interpreter 
to prevent the programmer from shooting him/herself in the foot, but it's not 
worth the performance hit.

> and it would make per-instance method overloading
> impossible (remember that OOP is about objects, not classes).

Yes again. While I was writing the above comment ("write operation on an 
attribute"), it *did* cross my mind that you might want to write 
self.attribute, even if it names a method, not a data-item.


Summary: I no longer suspect that "Python is broken". I *do* think that there's 
a situation that is potentially quite confusing:

 * In the statement "self.x = self.x + 1", the two "self.x" names can sometimes 
refer to different objects.

 * Even worse, in the equivalent statement "self.x += 1", the single name 
"self.x" can sometimes refer to two different objects!

I think this situation should be handled in documentation. (I'm a tech writer 
in my day job ... oh wait, I forgot ... I got laid off from my day job in 
December.) I'll look into what the standard Python doc set says on this matter.

-John

--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread R. David Murray
M R A Barnett  wrote:
> Aaron Brady wrote:
> [snip]
> > However, in my (opined) interpretation, 'list.append(...) is an in-
> > place operation' is a factual error.  In-place operations -also-
> > rebind their 'argument' (FLOBW for lack of better words).  'append' is
> > a by-side-effect operation.  However colloquially it's mostly
> > accurate.
> > 
> [snip]
> All the augmented assignments rebind, even for objects which support
> in-place operations. For example:
> 
>  my_list = []
>  my_list += [0]
> 
> rebinds, but the equivalent:
>
>  my_list = []
>  my_list.extend([0])
> 
> doesn't.

Lest someone be mislead by this discussion, how about an example:

>>> a = b = []
>>> a.extend([1])
>>> a
[1]
>>> b
[1]
>>> a += [3]
>>> a
[1, 3]
>>> b
[1, 3]
>>> a = a + [5]
>>> a
[1, 3, 5]
>>> b
[1, 3]

It is technically correct that '+=' bebinds 'a', but what it
rebinds it to is the same object that was just mutated.  Unlike
the '+' case where 'a' is bound to a newly created list object.

Personally I think += and kin were a bad idea and should have been
removed in Python 3.0 :)  Even though I occasionally use them.  (Maybe
I'll stop.)

> Augmented assignments which don't support in-place operations behave
> like normal assignments (binding). For example:
> 
>  my_int = 0
>  my_int += 1
> 
> behaves like:
> 
>  my_int = 0
>  my_int = my_int + 1

--
R. David Murray   http://www.bitdance.com

--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread Bruno Desthuilliers

John Posner a écrit :

(My apologies if the thread has already covered this.) I believe I
understand the WHAT in this situation, but I don't understand the WHY
...

Given this class definition:

class Cls(object): x = 345

... I observe the following, using IDLE 2.6.1:


inst = Cls() Cls.x is inst.x

True


Cls.x += 1 Cls.x is inst.x

True


inst.x += 1 Cls.x is inst.x

False

My question is ... WHY does the interpreter  silently create the
instance attribute at this point,


Becaause that's how you create instance attributes in Python. Why do you 
think 'self' - that is, a reference to some object - is mandatory in 
"methods" (really, functions) arguments list ?


Or do you mean that the existence of a synonym class attribute should be 
checked on each instance variable assignement ? This would probably be a 
big performance hit, and it would make per-instance method overloading 
impossible (remember that OOP is about objects, not classes).


--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread Matthew Woodcraft
"Rhodri James"  writes:

> But do you, though?  The only occasion I can think of that I'd want
> the search to go past the instance is this "auto-initialisation",
> and frankly I'd rather do that in an __init__ anyway.  Perhaps
> static methods or class methods work that way, I don't know how
> the innards of the interpreter handle that.
>
> Is there any actual advantage to self.attribute picking up
> Class.attribute instead of raising a NameError?

You use that any time you call an ordinary method using syntax like
'self.foo()'.

-M-
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread Bruno Desthuilliers

Rhodri James a écrit :
On Sun, 15 Mar 2009 17:55:25 -, Aaron Brady  
wrote:



On Mar 15, 12:39 pm, John Posner  wrote:

(snip)

Is there a beneficial effect of silently creating the instance 
attribute, which outweighs the detrimental effects: (1) 
inconsistency, (2) the "surprising" decoupling?


Yes.  If you access an attribute, you want the search to go like this:

- check instance for attribute
- check class for attribute
- check base classes for attribute


But do you, though?  The only occasion I can think of that I'd want
the search to go past the instance is this "auto-initialisation",


How would you resolve inst.method, then ?


and frankly I'd rather do that in an __init__ anyway.  Perhaps
static methods or class methods work that way, I don't know how
the innards of the interpreter handle that.

Is there any actual advantage to self.attribute picking up
Class.attribute instead of raising a NameError?


Yes: resolving methods and other descriptors.

--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread Matthew Woodcraft
John Posner  writes:

> My question is ... WHY does the interpreter silently create the
> instance attribute at this point, causing a "surprising decoupling"
> from the class attribute? WHY doesn't the interpreter behave as it
> would with a simple, non-instance variable:

>   > python
>   Python 2.6.1 ...
>   Type "help", "copyright", "credits" or "license" for more information.
>
>   >>> x += 1
>   Traceback (most recent call last):
> File "", line 1, in 
>   NameError: name 'x' is not defined

> Is there a beneficial effect of silently creating the instance
> attribute, which outweighs the detrimental effects: (1) inconsistency,
> (2) the "surprising" decoupling?

I doubt it's because anyone particularly wanted this behaviour; it just
falls out of the way '+=' is defined.

At the point where 'inst.x += 1' is compiled, Python doesn't know
whether 'inst.x' is going to turn out to be a class attribute or an
instance attribute or a property. So really the only thing it can do is
generate code to read inst.x in the usual way and then assign to inst.x
in the usual way (where 'the usual way' for CPython is LOAD_ATTR and
STORE_ATTR).

-M-
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread Rhodri James
On Sun, 15 Mar 2009 17:55:25 -, Aaron Brady   
wrote:



On Mar 15, 12:39 pm, John Posner  wrote:
(My apologies if the thread has already covered this.) I believe I  
understand the WHAT in this situation, but I don't understand the WHY  
...


[snip]

My question is ... WHY does the interpreter silently create the  
instance attribute at this point, causing a "surprising decoupling"  
from the class attribute? WHY doesn't the interpreter behave as it  
would with a simple, non-instance variable:


  > python
  Python 2.6.1 ...
  Type "help", "copyright", "credits" or "license" for more information.

  >>> x += 1
  Traceback (most recent call last):
    File "", line 1, in 
  NameError: name 'x' is not defined

Is there a beneficial effect of silently creating the instance  
attribute, which outweighs the detrimental effects: (1) inconsistency,  
(2) the "surprising" decoupling?


Yes.  If you access an attribute, you want the search to go like this:

- check instance for attribute
- check class for attribute
- check base classes for attribute


But do you, though?  The only occasion I can think of that I'd want
the search to go past the instance is this "auto-initialisation",
and frankly I'd rather do that in an __init__ anyway.  Perhaps
static methods or class methods work that way, I don't know how
the innards of the interpreter handle that.

Is there any actual advantage to self.attribute picking up
Class.attribute instead of raising a NameError?


If you write an attribute, you want it stored in the attribute, not

   ^

the class or base classes.


I think you meant "instance" there :-)  Actually what I want is for
the attribute to be stored where I told it, which could well be in
the class.  If the attribute is specified as "self.attribute", then
yes, put it in the instance.

--
Rhodri James *-* Wildebeeste Herder to the Masses
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread Aaron Brady
On Mar 15, 12:39 pm, John Posner  wrote:
> (My apologies if the thread has already covered this.) I believe I understand 
> the WHAT in this situation, but I don't understand the WHY ...
>
> Given this class definition:
>
>   class Cls(object):
>       x = 345
>
> ... I observe the following, using IDLE 2.6.1:
>
> >>> inst = Cls()
> >>> Cls.x is inst.x
>
> True
>
> >>> Cls.x += 1
> >>> Cls.x is inst.x
>
> True
>
> >>> inst.x += 1
> >>> Cls.x is inst.x
>
> False
>
> My question is ... WHY does the interpreter silently create the instance 
> attribute at this point, causing a "surprising decoupling" from the class 
> attribute? WHY doesn't the interpreter behave as it would with a simple, 
> non-instance variable:
>
>   > python
>   Python 2.6.1 ...
>   Type "help", "copyright", "credits" or "license" for more information.
>
>   >>> x += 1
>   Traceback (most recent call last):
>     File "", line 1, in 
>   NameError: name 'x' is not defined
>
> Is there a beneficial effect of silently creating the instance attribute, 
> which outweighs the detrimental effects: (1) inconsistency, (2) the 
> "surprising" decoupling?
>
> Tx,
> John

Yes.  If you access an attribute, you want the search to go like this:

- check instance for attribute
- check class for attribute
- check base classes for attribute

If you write an attribute, you want it stored in the attribute, not
the class or base classes.

...unless you're just picking on the augmented ops, in which case the
tradeoff is more subtle than stated.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread John Posner

(My apologies if the thread has already covered this.) I believe I understand 
the WHAT in this situation, but I don't understand the WHY ...

Given this class definition:

  class Cls(object):
  x = 345

... I observe the following, using IDLE 2.6.1:

>>> inst = Cls()
>>> Cls.x is inst.x
True

>>> Cls.x += 1
>>> Cls.x is inst.x
True

>>> inst.x += 1
>>> Cls.x is inst.x
False

My question is ... WHY does the interpreter silently create the instance 
attribute at this point, causing a "surprising decoupling" from the class 
attribute? WHY doesn't the interpreter behave as it would with a simple, 
non-instance variable:

  > python
  Python 2.6.1 ...
  Type "help", "copyright", "credits" or "license" for more information.

  >>> x += 1
  Traceback (most recent call last):
File "", line 1, in 
  NameError: name 'x' is not defined

Is there a beneficial effect of silently creating the instance attribute, which 
outweighs the detrimental effects: (1) inconsistency, (2) the "surprising" 
decoupling?

Tx,
John


--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread M R A Barnett

Aaron Brady wrote:
[snip]

However, in my (opined) interpretation, 'list.append(...) is an in-
place operation' is a factual error.  In-place operations -also-
rebind their 'argument' (FLOBW for lack of better words).  'append' is
a by-side-effect operation.  However colloquially it's mostly
accurate.


[snip]
All the augmented assignments rebind, even for objects which support
in-place operations. For example:

my_list = []
my_list += [0]

rebinds, but the equivalent:

my_list = []
my_list.extend([0])

doesn't.

Augmented assignments which don't support in-place operations behave
like normal assignments (binding). For example:

my_int = 0
my_int += 1

behaves like:

my_int = 0
my_int = my_int + 1
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread Aaron Brady
On Mar 15, 8:56 am, "Rhodri James" 
wrote:
> On Sun, 15 Mar 2009 13:26:17 -, Matthew Woodcraft  
>
>  wrote:
>
> [snip Gary Herron's explanation of instance attribute lookup
> falling back to class attribute lookup]
>
> > It seems clear to me that Maxim understood all this when he asked his
> > original question (you need to understand this subtlety to know why
> > the trick he was asking about only works for immutable values).
>
> It seems equally clear to me that Maxim didn't understand any of this
> when he asked his original question, since he appeared to view class
> attributes purely as initialisers.
>
> Given that either of us could be right, Gary's assumption of less
> understanding rather than more is clearly the safer one to take.
>
> --
> Rhodri James *-* Wildebeeste Herder to the Masses

It's interesting Rhodri chose the safety dimension as the deciding
factor: Gary's assumption might have other faults, but it's safer, and
(by Grice's maxim of quantity,) therefore better.  In it's form:

M: Safer is better.
m: Gary's assumption is safer.
C: Gary's assumption is better.

There are two empirical claims, specifically the major and minor
premises.  It's not clear that either is true, but I think it's a
mistake to make a blanket judgment of net safety between competing
goods.

Long story short, it's safe for our pride, by cutting down outsiders,
but it's not safe for our publicity.

As for the discussion, Gary said it: 'self.list = self.list + [i]' is
a private write, but has other dangers such as running time and stored
references.

However, in my (opined) interpretation, 'list.append(...) is an in-
place operation' is a factual error.  In-place operations -also-
rebind their 'argument' (FLOBW for lack of better words).  'append' is
a by-side-effect operation.  However colloquially it's mostly
accurate.

And to the OP, your method works for immutable class members, and even
certain uses of mutable ones.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread Bruno Desthuilliers

Maxim Khitrov a écrit :

On Sat, Mar 14, 2009 at 2:07 PM, Gary Herron  wrote:

Maxim Khitrov wrote:

Very simple question on the preferred coding style. I frequently write
classes that have some data members initialized to immutable values.
For example:

class Test(object):
   def __init__(self):
   self.some_value = 0
   self.another_value = None

Similar effect can be achieved by defining some_value and
another_value for the entire class, like so:

class Test(object):
   some_value = 0
   another_value = None

The advantage of doing this is that the assignments are evaluated once
and thus the creation of that class is a bit faster. Access is still
performed through self.some_value and self.another_value. Is there a
reason to prefer the first style over the second?

- Max
--
http://mail.python.org/mailman/listinfo/python-list


Such things are often called class attributes, and the are fine.  If you
look through Python's standard library,  you will find many examples of
class attributes.

However, you appear to have either a misuse or misconception of the word
"immutable' here.   Whether the value you assign to a class attribute is
mutable or immutable is irrelevant.   Also whether you plan on leaving the
value constant or not is also not relevant.
What does matter is this:  If every instance wants access to a single value
(immutable or not), use a class attribute, otherwise use an instance
attribute.

Gary Herron


Perhaps a different example would help explain what I'm trying to do:

class Case1(object):
def __init__(self):
self.count = 0
self.list  = []

def inc(self):
self.count += 1
self.list.append(self.count)

def val(self):
return (self.count, self.list)

class Case2(object):
count = 0
list  = []

def inc(self):
self.count += 1


This above statement does 3 things:

1/ read "self.count", which, *the first time this method is called*, 
resolves to self.__class__.count since by that time, there's no instance 
attribute named 'count'


2/ add one to the int object returned by looking up 'self.count'

3/ store the result as instance attribute named 'count'.

IOW, the first calls to the method reads the class 'count' attribute and 
creates the instance 'count' attribute. Subsequent calls will resolve 
'self.count' as the instance attribute since it now exists.




self.list.append(self.count)


And this statement:

1/ read 'self.list', which resolves to self.__class__.list (the class 
attribute) since there's no instance attribute named 'list'


2/ mutate the class attribute



The only difference between Case1 and Case2 classes is where the count
and list attributes are defined. You will notice that for an immutable
type (count), this doesn't matter.


cf above.


On the last line, v1 == v2 is
always True. When the type is mutable (list), you must define it in
__init__.


Try rebinding self.list instead of mutating it, and you'll find out that 
it's not related to immutable/mutable types, but to how Python's object 
model works wrt/ attribute lookup and attribute binding.


An simple example being worth a thousand words:

class Case3(object):
count = 0
list  = []

def inc(self):
print self.__dict__
self.count += 1
self.list = self.list + [self.count]
print self.__dict__

def val(self):
return (self.count, self.list)

>>> c = Case3()
>>> print c.__dict__
{}
>>> print c.__class__.__dict__
{'count': 0, '__module__': '__main__', 'val': 0xb7c7bd4c>, 'list': [], '__dict__': objects>, '__weakref__': , 
'__doc__': None, 'inc': }

>>> c.inc()
{}
{'count': 1, 'list': [1]}
>>> print c.__dict__
{'count': 1, 'list': [1]}
>>> print c.__class__.__dict__
{'count': 0, '__module__': '__main__', 'val': 0xb7c7bd4c>, 'list': [], '__dict__': objects>, '__weakref__': , 
'__doc__': None, 'inc': }

>>>



This isn't about class attributes or shared instance
attributes/constants.


Yes, it is.


This is about a small optimization in defining
per-instance variables. This optimization only applies to immutable
types.


Wrong conclusions, sorry.

HTH
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread Rhodri James
On Sun, 15 Mar 2009 15:05:04 -, Matthew Woodcraft  
 wrote:



"Rhodri James"  writes:


On Sun, 15 Mar 2009 13:26:17 -, Matthew Woodcraft



It seems clear to me that Maxim understood all this when he asked his
original question (you need to understand this subtlety to know why
the trick he was asking about only works for immutable values).


It seems equally clear to me that Maxim didn't understand any of this
when he asked his original question, since he appeared to view class
attributes purely as initialisers.


Not at all.

He said: << Look, here's a tricky way to use a class attribute as an
initialiser. Is this good style? >>.

What was there in his post that makes you think he viewed class
attributes purely as initialisers?


My lack of sleep :-(

--
Rhodri James *-* Wildebeeste Herder to the Masses
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread Matthew Woodcraft
"Rhodri James"  writes:

> On Sun, 15 Mar 2009 13:26:17 -, Matthew Woodcraft

>> It seems clear to me that Maxim understood all this when he asked his
>> original question (you need to understand this subtlety to know why
>> the trick he was asking about only works for immutable values).
>
> It seems equally clear to me that Maxim didn't understand any of this
> when he asked his original question, since he appeared to view class
> attributes purely as initialisers.

Not at all.

He said: << Look, here's a tricky way to use a class attribute as an
initialiser. Is this good style? >>.

What was there in his post that makes you think he viewed class
attributes purely as initialisers?


> Given that either of us could be right, Gary's assumption of less
> understanding rather than more is clearly the safer one to take.

As a general rule, making that assumption runs the risk of being rude or
patronising, so the respondent should be very careful how to phrase the
response. c.l.py is friendlier than many newsgroups, but it could still
do much better.


But in this particular case, statements like
> However, you appear to have either a misuse or misconception of the
> word "immutable' here. Whether the value you assign to a class
> attribute is mutable or immutable is irrelevant.

are wrong as well as unhelpfully phrased.

-M-

--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread Rhodri James
On Sun, 15 Mar 2009 13:26:17 -, Matthew Woodcraft  
 wrote:


[snip Gary Herron's explanation of instance attribute lookup
falling back to class attribute lookup]


It seems clear to me that Maxim understood all this when he asked his
original question (you need to understand this subtlety to know why
the trick he was asking about only works for immutable values).


It seems equally clear to me that Maxim didn't understand any of this
when he asked his original question, since he appeared to view class
attributes purely as initialisers.

Given that either of us could be right, Gary's assumption of less
understanding rather than more is clearly the safer one to take.

--
Rhodri James *-* Wildebeeste Herder to the Masses
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-15 Thread Matthew Woodcraft
Gary Herron  writes:

> Gary Herron  wrote:
> No, you are still misinterpreting your results.  But you can be forgiven
> because this is quite a subtle point about Python's attribute access.
>
> Here's how it works:
>
> On access, self.count (or self.anything) attempts to find "count" in
> the instance variable "self". If that fails, it attempts to lookup
> "count" in the class. If that fails it attempts to lookup "count" in a
> global context, ...). However, on assignment self.count=... *must*
> necessarily mean the local instance variable -- no defaulting to a
> class variable on assignment.
>
> So ...
>
> With your class C2, the line
>   self.count +=1
> which really translates into
>   self.count = self.count + 1
> has two different actions depending on the pass through the inner loop.
> The first time through (when no instance variable "count" exists), that line
> means
> =  + 1
> and succeeding passes through (now that self.count is defined) become
> =  +1
> which is now the same as your class C1
>
> To complete the subtlety, if you were to do
>   self.list = self.list + [i]
> you would see list behaving just as count.  However since,
>list.append(...)
> is an in-place operation, and not an assignment, the creation of an instance
> variable
> is not provoked, and so all instances continue using the single class
> variable.

It seems clear to me that Maxim understood all this when he asked his
original question (you need to understand this subtlety to know why
the trick he was asking about only works for immutable values).

I wish people on this mailing list|newsgroup would be a little more
ready to assume that people really are asking the question they wrote,
and not the FAQ that sounds most like it.

-M-

--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-14 Thread Gary Herron

Maxim Khitrov wrote:

On Sat, Mar 14, 2009 at 5:38 PM, Matthew Woodcraft
 wrote:
  

Gary Herron  writes:
I think this code is in poor taste: it's clear that it will confuse
people (which is what Maxim was asking about in the first place).



Careful now -- I didn't write that.  (Although I agree that it is 
confusing.)


Gary Herron



Yes, I see that now, thanks :)

- Max
--
http://mail.python.org/mailman/listinfo/python-list
  


--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-14 Thread Gary Herron

Maxim Khitrov wrote:

On Sat, Mar 14, 2009 at 4:31 PM, Gary Herron  wrote:
  

Perhaps a different example would help explain what I'm trying to do:

class Case1(object):
   def __init__(self):
   self.count = 0
   self.list  = []

   def inc(self):
   self.count += 1
   self.list.append(self.count)

   def val(self):
   return (self.count, self.list)

class Case2(object):
   count = 0
   list  = []

   def inc(self):
   self.count += 1
   self.list.append(self.count)

   def val(self):
   return (self.count, self.list)

for i in xrange(10):
   c1 = Case1()
   c2 = Case2()

   for j in xrange(i):
   c1.inc()
   c2.inc()

   v1, l1 = c1.val()
   v2, l2 = c2.val()

   print v1 == v2, l1 == l2

The only difference between Case1 and Case2 classes is where the count
and list attributes are defined. You will notice that for an immutable
type (count), this doesn't matter. On the last line, v1 == v2 is
always True. When the type is mutable (list), you must define it in
__init__. This isn't about class attributes or shared instance
attributes/constants. This is about a small optimization in defining
per-instance variables. This optimization only applies to immutable
types.

- Max
--
http://mail.python.org/mailman/listinfo/python-list

  

But now you are not listening to what people are telling you.  It has
*nothing* to do with the mutability/immutability of the integer and the list
your two classes create.

The difference is this:

  For C1:  You create 10 instances of C1.  Each one creates its own  count,
and a list variables, and manipulates them calls to inc and val.  Then each
on is discarded as you go through the next pass on the outer loop.



Correct, though the discarded part makes no difference.

  

  For C2;  You create 10 instances of C2, but these 10 instances each
manipulate values created once in the class itself.  The values manipulated
by one instance of C2 in one pass through the loop are not affected when, on
the next pass through the loop, that instance is destroyed and another
instance is created.
So...



Incorrect. Only the count is unaffected, which was the whole point of
my question.
  



No, you are still misinterpreting your results.  But you can be forgiven 
because this is quite a subtle point about Python's attribute access.


Here's how it works:

On access, self.count (or self.anything) attempts to find "count" in the 
instance variable "self".  If that fails, it attempts to lookup "count" 
in the class.  If that fails it attempts to lookup "count" in a global 
context, ...).However, on assignment self.count=... *must* 
necessarily mean the local instance variable -- no defaulting to a class 
variable on assignment.


So ... 


With your class C2, the line
  self.count +=1
which really translates into
  self.count = self.count + 1
has two different actions depending on the pass through the inner loop.
The first time through (when no instance variable "count" exists), that 
line means
= count> + 1

and succeeding passes through (now that self.count is defined) become
=  +1
which is now the same as your class C1

To complete the subtlety, if you were to do
  self.list = self.list + [i]
you would see list behaving just as count.  However since,
   list.append(...)
is an in-place operation, and not an assignment, the creation of an 
instance variable
is not provoked, and so all instances continue using the single class 
variable.


There is a lesson to be learned here.

Class variables can't be the target of an assignment through self, 
because that
creates an instance variable.  You can, however, assign to a class 
variable through

the class:
 C2.count = ...



  




 If you want a variable that records/supplies some value across *all*
instances of a class, use a class variable.  (Or use a global variable -- it
would have the same effect.)

 If you want a variable whose value is unique to each instance of a class,
then make it an instance variable.

Gary Herron



I never thought that such simple question would turn into this. David
Stanek gave me the answer I was looking for (thank you). You, on the
other hand, are still going after the wrong issue. Once again, here's
the same example using Terry's suggestions. No class instances are
being destroyed until the very end.

class Case1(object):
   def __init__(self):
   self.count = 0
   self.list  = []

   def inc(self):
   self.count += 1
   self.list.append(self.count)

   def val(self):
   return (self.count, self.list)

class Case2(object):
   count = 0
   list  = []

   def inc(self):
   self.count += 1
   self.list.append(self.count)

   def val(self):
   return (self.count, self.list)

c1a, c1b = Case1(), Cas

Re: Style question - defining immutable class data members

2009-03-14 Thread Torsten Bronger
Hallöchen!

Maxim Khitrov writes:

> [...]
>
> The advantage of doing this is that the assignments are evaluated
> once and thus the creation of that class is a bit faster. Access
> is still performed through self.some_value and
> self.another_value. Is there a reason to prefer the first style
> over the second?

I think that tools like epydoc can generate more accurate API
documentation if you write them as instance attributes.

Tschö,
Torsten.

-- 
Torsten Bronger, aquisgrana, europa vetus
   Jabber ID: torsten.bron...@jabber.rwth-aachen.de
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-14 Thread Maxim Khitrov
On Sat, Mar 14, 2009 at 5:38 PM, Matthew Woodcraft
 wrote:
> Gary Herron  writes:
> I think this code is in poor taste: it's clear that it will confuse
> people (which is what Maxim was asking about in the first place).

Yes, I see that now, thanks :)

- Max
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-14 Thread Maxim Khitrov
On Sat, Mar 14, 2009 at 4:31 PM, Gary Herron  wrote:
>> Perhaps a different example would help explain what I'm trying to do:
>>
>> class Case1(object):
>>        def __init__(self):
>>                self.count = 0
>>                self.list  = []
>>
>>        def inc(self):
>>                self.count += 1
>>                self.list.append(self.count)
>>
>>        def val(self):
>>                return (self.count, self.list)
>>
>> class Case2(object):
>>        count = 0
>>        list  = []
>>
>>        def inc(self):
>>                self.count += 1
>>                self.list.append(self.count)
>>
>>        def val(self):
>>                return (self.count, self.list)
>>
>> for i in xrange(10):
>>        c1 = Case1()
>>        c2 = Case2()
>>
>>        for j in xrange(i):
>>                c1.inc()
>>                c2.inc()
>>
>>        v1, l1 = c1.val()
>>        v2, l2 = c2.val()
>>
>>        print v1 == v2, l1 == l2
>>
>> The only difference between Case1 and Case2 classes is where the count
>> and list attributes are defined. You will notice that for an immutable
>> type (count), this doesn't matter. On the last line, v1 == v2 is
>> always True. When the type is mutable (list), you must define it in
>> __init__. This isn't about class attributes or shared instance
>> attributes/constants. This is about a small optimization in defining
>> per-instance variables. This optimization only applies to immutable
>> types.
>>
>> - Max
>> --
>> http://mail.python.org/mailman/listinfo/python-list
>>
>
> But now you are not listening to what people are telling you.  It has
> *nothing* to do with the mutability/immutability of the integer and the list
> your two classes create.
>
> The difference is this:
>
>   For C1:  You create 10 instances of C1.  Each one creates its own  count,
> and a list variables, and manipulates them calls to inc and val.  Then each
> on is discarded as you go through the next pass on the outer loop.

Correct, though the discarded part makes no difference.

>   For C2;  You create 10 instances of C2, but these 10 instances each
> manipulate values created once in the class itself.  The values manipulated
> by one instance of C2 in one pass through the loop are not affected when, on
> the next pass through the loop, that instance is destroyed and another
> instance is created.
> So...

Incorrect. Only the count is unaffected, which was the whole point of
my question.

>  If you want a variable that records/supplies some value across *all*
> instances of a class, use a class variable.  (Or use a global variable -- it
> would have the same effect.)
>
>  If you want a variable whose value is unique to each instance of a class,
> then make it an instance variable.
>
> Gary Herron

I never thought that such simple question would turn into this. David
Stanek gave me the answer I was looking for (thank you). You, on the
other hand, are still going after the wrong issue. Once again, here's
the same example using Terry's suggestions. No class instances are
being destroyed until the very end.

class Case1(object):
   def __init__(self):
   self.count = 0
   self.list  = []

   def inc(self):
   self.count += 1
   self.list.append(self.count)

   def val(self):
   return (self.count, self.list)

class Case2(object):
   count = 0
   list  = []

   def inc(self):
   self.count += 1
   self.list.append(self.count)

   def val(self):
   return (self.count, self.list)

c1a, c1b = Case1(), Case1()
c2a, c2b = Case2(), Case2()

c1a.inc(), c1b.inc()
c2a.inc(), c2b.inc()

print c1a.val(), c1b.val(), c2a.val(), c2b.val()

And the output:
(1, [1]), (1, [1]), (1, [1, 1]), (1, [1, 1])

The first element of every tuple is the same. This is the count, which
is immutable. The second element is not the same for c2[a,b]. This is
the list, which is mutable. My question was about immutable values,
and for those the who cases are identical. In the second case, c2a and
c2b begin with count referring to the same '0' object. This is where
the time and space savings are made. But because that object is
immutable, when += 1 operation is performed, a copy is made for each
instance. At that point, I am not sharing any values between class
instances.

The whole point is that this is a quick(er) way of providing initial
values for class instance variables when those values are immutable.
When/if that initial value is changed, a copy is made. In Case1, that
copy is made from the very begging in __init__. Please try to
understand what the question is about before responding to it.

- Max
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-14 Thread Matthew Woodcraft
Gary Herron  writes:

> But now you are not listening to what people are telling you.  It has
> *nothing* to do with the mutability/immutability of the integer and the list
> your two classes create.

No! Did you run the code he posted? The immutability makes all the
difference.


> The difference is this:

>For C1: You create 10 instances of C1. Each one creates its own
> count, and a list variables, and manipulates them calls to inc and
> val. Then each on is discarded as you go through the next pass on the
> outer loop.

>For C2; You create 10 instances of C2, but these 10 instances each
> manipulate values created once in the class itself. The values
> manipulated by one instance of C2 in one pass through the loop are not
> affected when, on the next pass through the loop, that instance is
> destroyed and another instance is created.

If you try it, you will see that this isn't true for C2, in the case of
the immutable object. That's because given this code:

  class Foo(object):
  x = 0

  def inc(self):
  self.x += 1

when inc is called, it creates an 'x' attribute on the instance, even
though one didn't exist before, and it doesn't change the value of the
class attribute.

If 'x' were a list, the new instance attribute would refer to the same
object as the class attribute, so it wouldn't make much difference. But
when the original class attribute was an immutable object, they become
'decoupled'.


I think this code is in poor taste: it's clear that it will confuse
people (which is what Maxim was asking about in the first place).

-M-
--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-14 Thread Terry Reedy

Maxim Khitrov wrote:


Perhaps a different example would help explain what I'm trying to do:

class Case1(object):
def __init__(self):
self.count = 0
self.list  = []

def inc(self):
self.count += 1
self.list.append(self.count)

def val(self):
return (self.count, self.list)


OK, so .count and .list (BAD IDEA TO USE BUILT-IN NAME)  are not 
constants, as you previously implied.




class Case2(object):
count = 0
list  = []

def inc(self):
self.count += 1
self.list.append(self.count)

def val(self):
return (self.count, self.list)

for i in xrange(10):


You really only need one value of i for a test.  But you need multiple 
instances of each class



c1 = Case1()
c2 = Case2()


c1a, c1b = Case1(), Case1()
c2a, c2b = Case2(), Case2()


for j in xrange(i):
c1.inc()
c2.inc()


c1a.inc(), c1b.inc()
c2a.inc(), c2b,inc()


v1, l1 = c1.val()
v2, l2 = c2.val()


print(c1a.val(), c1b.val(), c2a.val(), c2b.val())


print v1 == v2, l1 == l2


# just look as all four tuples


The only difference between Case1 and Case2 classes is where the count
and list attributes are defined.


and that 'only difference makes a major difference.  Make two instances 
of each class and you will see how.


Terry Jan Reedy


--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-14 Thread Gary Herron

Maxim Khitrov wrote:

On Sat, Mar 14, 2009 at 2:07 PM, Gary Herron  wrote:
  

Maxim Khitrov wrote:


Very simple question on the preferred coding style. I frequently write
classes that have some data members initialized to immutable values.
For example:

class Test(object):
   def __init__(self):
   self.some_value = 0
   self.another_value = None

Similar effect can be achieved by defining some_value and
another_value for the entire class, like so:

class Test(object):
   some_value = 0
   another_value = None

The advantage of doing this is that the assignments are evaluated once
and thus the creation of that class is a bit faster. Access is still
performed through self.some_value and self.another_value. Is there a
reason to prefer the first style over the second?

- Max
--
http://mail.python.org/mailman/listinfo/python-list

  

Such things are often called class attributes, and the are fine.  If you
look through Python's standard library,  you will find many examples of
class attributes.

However, you appear to have either a misuse or misconception of the word
"immutable' here.   Whether the value you assign to a class attribute is
mutable or immutable is irrelevant.   Also whether you plan on leaving the
value constant or not is also not relevant.
What does matter is this:  If every instance wants access to a single value
(immutable or not), use a class attribute, otherwise use an instance
attribute.

Gary Herron



Perhaps a different example would help explain what I'm trying to do:

class Case1(object):
def __init__(self):
self.count = 0
self.list  = []

def inc(self):
self.count += 1
self.list.append(self.count)

def val(self):
return (self.count, self.list)

class Case2(object):
count = 0
list  = []

def inc(self):
self.count += 1
self.list.append(self.count)

def val(self):
return (self.count, self.list)

for i in xrange(10):
c1 = Case1()
c2 = Case2()

for j in xrange(i):
c1.inc()
c2.inc()

v1, l1 = c1.val()
v2, l2 = c2.val()

print v1 == v2, l1 == l2

The only difference between Case1 and Case2 classes is where the count
and list attributes are defined. You will notice that for an immutable
type (count), this doesn't matter. On the last line, v1 == v2 is
always True. When the type is mutable (list), you must define it in
__init__. This isn't about class attributes or shared instance
attributes/constants. This is about a small optimization in defining
per-instance variables. This optimization only applies to immutable
types.

- Max
--
http://mail.python.org/mailman/listinfo/python-list
  


But now you are not listening to what people are telling you.  It has 
*nothing* to do with the mutability/immutability of the integer and the 
list your two classes create.


The difference is this:

   For C1:  You create 10 instances of C1.  Each one creates its own  
count, and a list variables, and manipulates them calls to inc and val.  
Then each on is discarded as you go through the next pass on the outer loop.


   For C2;  You create 10 instances of C2, but these 10 instances each 
manipulate values created once in the class itself.  The values 
manipulated by one instance of C2 in one pass through the loop are not 
affected when, on the next pass through the loop, that instance is 
destroyed and another instance is created. 


So...

 If you want a variable that records/supplies some value across *all* 
instances of a class, use a class variable. 
 (Or use a global variable -- it would have the same effect.)


 If you want a variable whose value is unique to each instance of a 
class, then make it an instance variable.


Gary Herron

--
http://mail.python.org/mailman/listinfo/python-list


Re: Style question - defining immutable class data members

2009-03-14 Thread David Stanek
On Sat, Mar 14, 2009 at 12:32 PM, Maxim Khitrov  wrote:
> Very simple question on the preferred coding style. I frequently write
> classes that have some data members initialized to immutable values.
> For example:
>
> class Test(object):
>    def __init__(self):
>        self.some_value = 0
>        self.another_value = None
>
> Similar effect can be achieved by defining some_value and
> another_value for the entire class, like so:
>
> class Test(object):
>    some_value = 0
>    another_value = None
>
> The advantage of doing this is that the assignments are evaluated once
> and thus the creation of that class is a bit faster. Access is still
> performed through self.some_value and self.another_value. Is there a
> reason to prefer the first style over the second?
>

In general I think it can be fine as long as you do use immutable
values. I use this pattern when I create data transfer objects[0].
Normally these objects don't have any methods. So you want to be
careful that you are doing it for the right reason. When I create
objects that are not DTOs I don't do this.

[0] http://martinfowler.com/eaaCatalog/dataTransferObject.html

-- 
David
blog: http://www.traceback.org
twitter: http://twitter.com/dstanek
--
http://mail.python.org/mailman/listinfo/python-list


  1   2   >