Re: [Tutor] A class that instantiates conditionally ?

2011-03-03 Thread Steven D'Aprano

David wrote:


class MyClass_2(object):
   def __new__(self, condition):
if condition:
  return object.__new__(self)
else:
  return None


[...]

Spot on. It would require two "if" tests, one inside __new__() and
another in the code.


You will always need at least two if tests: once in the function 
producing the result ("does the test succeed? if not, return this 
instead...") and once in the code using the result ("did the magic value 
get returned?").


Consider str.find()... the caller has to check whether it returns -1, 
but the find method itself has to check whether the search string is 
found or not, and return -1 if it is not. This may or may not require a 
*literal* if statement, but there's still an implied test in the code.




I found your mention of try/except there especially helpful, because
it was a pertinent reminder that I was not thinking in "ask forgiveness
not permission" mode. This (newbie mistake) occurred because I
wanted my application to continue, not abort with an exception, but
after your prompt I recalled that "except" doesn't have to raise exceptions
it can do other things.


Fair enough, and arguably having the class raise an exception is a 
better design, but with all the people saying your original design was 
"too clever", I'd like to give it some love :) I think the design is 
just clever enough. I would consider using it if I were designing 
something like the regular expression match and search methods, which 
return None if the regex doesn't match.




--
Steven
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] A class that instantiates conditionally ?

2011-03-02 Thread Izz ad-Din Ruhulessin
Of course that would be:

> foo = lambda condition: MyClass() if condition else None


2011/3/3 Izz ad-Din Ruhulessin 

> Maybe:
>
> foo = lambda x: MyClass() if condition else None
>
>
> 2011/3/3 David 
>
> Another classic case of trying something not the best way, due to
>>  inexperience.
>> But it has been a good process: I learned something new from
>> setting myself the initial puzzle and then finding a solution,and then
>> learned more from the great tutoring here. Thanks very much for all
>> the replies.
>>
>> On 2 March 2011 03:31, Alan Gauld  wrote:
>> >
>> >> class MyClass_2(object):
>> >>def __new__(self, condition):
>> >> if condition:
>> >>   return object.__new__(self)
>> >> else:
>> >>   return None
>> >
>> > Thats pretty much how I'd do it.
>>
>> Thanks for reviewing my code.
>>
>> On 2 March 2011 03:35, Alan Gauld  wrote:
>> >
>> > Oops, sent too soon.
>> >
>> > I meant to add that you should realize that the implication of your
>> > design is that the user of the class now has to check each object
>> > to see if it is a valid reference or None. You could raise an exception
>> > instead of returning None which allows a try/except style...
>> >
>> > This extra overhead is one reason these kinds of "clever" tricks
>> > are usually avoided. A valid object with null content is often
>> > preferrable, or a singleton style pattern. But occasionally your
>> > style is needed, just be aware of the extra overhead you
>> > introduce by using it.
>>
>> Spot on. It would require two "if" tests, one inside __new__() and
>> another in the code.
>>
>> I found your mention of try/except there especially helpful, because
>> it was a pertinent reminder that I was not thinking in "ask forgiveness
>> not permission" mode. This (newbie mistake) occurred because I
>> wanted my application to continue, not abort with an exception, but
>> after your prompt I recalled that "except" doesn't have to raise
>> exceptions
>> it can do other things.
>>
>> So I went in the direction you suggested and I am happy with the results.
>> Basically my application is interpreting binary file data by instantiating
>> a
>> structured object for each file in a fixed list of binary files, and I
>> was looking
>> for a neat way to ignore any errors on files that might not be present
>> (failed to open). So, after feedback here my solution now is to use
>> try/except in the class __init__() to create a valid object with null
>> content,
>> and then use "if" tests in the rest of the code that processes the objects
>> to
>> just ignore them if they are null, which is a nice clear way to do it.
>>
>> On 2 March 2011 20:44, Steven D'Aprano  wrote:
>> >
>> > By convention, the name of the first argument to __new__ is cls, not
>> self,
>> > because it is bound to the class object itself (MyClass_2 in this
>> example)
>> > rather than the instance. The instance doesn't yet exist, so that's not
>> > surprising!
>>
>> Thanks for pointing that out. In 2.6 Language Reference 3.4.3 they used
>> "mcs" (metaclass?) which I didn't comprehend at all at the time (the
>> mindset
>> of just wanting to get some code working to fix a problem is not the most
>> helpful mindset for decoding a large body of new information), so I just
>> used
>> "self" when getting their example code to work for me. In Section 3.4.1
>> they
>> use "cls" which I now see clearly and understand thanks.
>>
>> On 3 March 2011 03:03, Knacktus  wrote:
>> >
>> > I think that's too clever ;-).
>>
>> I agree now .. but it was a useful experiment. Thanks for the tute.
>> ___
>> Tutor maillist  -  Tutor@python.org
>> To unsubscribe or change subscription options:
>> http://mail.python.org/mailman/listinfo/tutor
>>
>
>
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] A class that instantiates conditionally ?

2011-03-02 Thread Izz ad-Din Ruhulessin
Maybe:

foo = lambda x: MyClass() if condition else None


2011/3/3 David 

> Another classic case of trying something not the best way, due to
>  inexperience.
> But it has been a good process: I learned something new from
> setting myself the initial puzzle and then finding a solution,and then
> learned more from the great tutoring here. Thanks very much for all
> the replies.
>
> On 2 March 2011 03:31, Alan Gauld  wrote:
> >
> >> class MyClass_2(object):
> >>def __new__(self, condition):
> >> if condition:
> >>   return object.__new__(self)
> >> else:
> >>   return None
> >
> > Thats pretty much how I'd do it.
>
> Thanks for reviewing my code.
>
> On 2 March 2011 03:35, Alan Gauld  wrote:
> >
> > Oops, sent too soon.
> >
> > I meant to add that you should realize that the implication of your
> > design is that the user of the class now has to check each object
> > to see if it is a valid reference or None. You could raise an exception
> > instead of returning None which allows a try/except style...
> >
> > This extra overhead is one reason these kinds of "clever" tricks
> > are usually avoided. A valid object with null content is often
> > preferrable, or a singleton style pattern. But occasionally your
> > style is needed, just be aware of the extra overhead you
> > introduce by using it.
>
> Spot on. It would require two "if" tests, one inside __new__() and
> another in the code.
>
> I found your mention of try/except there especially helpful, because
> it was a pertinent reminder that I was not thinking in "ask forgiveness
> not permission" mode. This (newbie mistake) occurred because I
> wanted my application to continue, not abort with an exception, but
> after your prompt I recalled that "except" doesn't have to raise exceptions
> it can do other things.
>
> So I went in the direction you suggested and I am happy with the results.
> Basically my application is interpreting binary file data by instantiating
> a
> structured object for each file in a fixed list of binary files, and I
> was looking
> for a neat way to ignore any errors on files that might not be present
> (failed to open). So, after feedback here my solution now is to use
> try/except in the class __init__() to create a valid object with null
> content,
> and then use "if" tests in the rest of the code that processes the objects
> to
> just ignore them if they are null, which is a nice clear way to do it.
>
> On 2 March 2011 20:44, Steven D'Aprano  wrote:
> >
> > By convention, the name of the first argument to __new__ is cls, not
> self,
> > because it is bound to the class object itself (MyClass_2 in this
> example)
> > rather than the instance. The instance doesn't yet exist, so that's not
> > surprising!
>
> Thanks for pointing that out. In 2.6 Language Reference 3.4.3 they used
> "mcs" (metaclass?) which I didn't comprehend at all at the time (the
> mindset
> of just wanting to get some code working to fix a problem is not the most
> helpful mindset for decoding a large body of new information), so I just
> used
> "self" when getting their example code to work for me. In Section 3.4.1
> they
> use "cls" which I now see clearly and understand thanks.
>
> On 3 March 2011 03:03, Knacktus  wrote:
> >
> > I think that's too clever ;-).
>
> I agree now .. but it was a useful experiment. Thanks for the tute.
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] A class that instantiates conditionally ?

2011-03-02 Thread David
Another classic case of trying something not the best way, due to
 inexperience.
But it has been a good process: I learned something new from
setting myself the initial puzzle and then finding a solution,and then
learned more from the great tutoring here. Thanks very much for all
the replies.

On 2 March 2011 03:31, Alan Gauld  wrote:
>
>> class MyClass_2(object):
>>def __new__(self, condition):
>> if condition:
>>   return object.__new__(self)
>> else:
>>   return None
>
> Thats pretty much how I'd do it.

Thanks for reviewing my code.

On 2 March 2011 03:35, Alan Gauld  wrote:
>
> Oops, sent too soon.
>
> I meant to add that you should realize that the implication of your
> design is that the user of the class now has to check each object
> to see if it is a valid reference or None. You could raise an exception
> instead of returning None which allows a try/except style...
>
> This extra overhead is one reason these kinds of "clever" tricks
> are usually avoided. A valid object with null content is often
> preferrable, or a singleton style pattern. But occasionally your
> style is needed, just be aware of the extra overhead you
> introduce by using it.

Spot on. It would require two "if" tests, one inside __new__() and
another in the code.

I found your mention of try/except there especially helpful, because
it was a pertinent reminder that I was not thinking in "ask forgiveness
not permission" mode. This (newbie mistake) occurred because I
wanted my application to continue, not abort with an exception, but
after your prompt I recalled that "except" doesn't have to raise exceptions
it can do other things.

So I went in the direction you suggested and I am happy with the results.
Basically my application is interpreting binary file data by instantiating a
structured object for each file in a fixed list of binary files, and I
was looking
for a neat way to ignore any errors on files that might not be present
(failed to open). So, after feedback here my solution now is to use
try/except in the class __init__() to create a valid object with null content,
and then use "if" tests in the rest of the code that processes the objects to
just ignore them if they are null, which is a nice clear way to do it.

On 2 March 2011 20:44, Steven D'Aprano  wrote:
>
> By convention, the name of the first argument to __new__ is cls, not self,
> because it is bound to the class object itself (MyClass_2 in this example)
> rather than the instance. The instance doesn't yet exist, so that's not
> surprising!

Thanks for pointing that out. In 2.6 Language Reference 3.4.3 they used
"mcs" (metaclass?) which I didn't comprehend at all at the time (the mindset
of just wanting to get some code working to fix a problem is not the most
helpful mindset for decoding a large body of new information), so I just used
"self" when getting their example code to work for me. In Section 3.4.1 they
use "cls" which I now see clearly and understand thanks.

On 3 March 2011 03:03, Knacktus  wrote:
>
> I think that's too clever ;-).

I agree now .. but it was a useful experiment. Thanks for the tute.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] A class that instantiates conditionally ?

2011-03-02 Thread Knacktus

Am 01.03.2011 07:49, schrieb David:

I have an idea that might clean up my code slightly, if I can make one
of my classes
clever enough to refuse to instantiate itself if a necessary condition
is not met.


I think that's too clever ;-). Instead, you could create a function 
which has the only and explicit purpose to decide wether or not to 
create the class, e.g.


def class_for_condition(condition):
if condition:
return MyClass()
return None

and use this throughout your code, e.g.

my_object = class_for_condition(condition)

But to me, it sounds a bit like trouble in general. As Alan said, you 
have to deal with two options for my_object in the remaining code. I 
can't really judge without seeing what you want to do later on, but 
maybe you have the chance to branch on a higher abstraction level?


if condition:
do_all_this_stuff() # do the things with my_object
else:
do_the_other_stuff() # do the things you don't need my_object

Cheers,

Jan



Below I propose some example code that seems to achieve this, and I am
asking here
for feedback on it, because I have not written much python. So I might be doing
something unwise due to fiddling with things I don't totally understand.

My aim is that instead of writing this:

class MyClass:
pass

condition = 0

if condition:
my_object = MyClass()
else:
my_object = None

I could instead write this:

class MyClass_2:
# put the if-test here inside the class

my_object_2 = MyClass_2(condition)

to achieve the goal that (my_object_2 == None) when (condition == False).

I read the (ver 2.6) Python Language Reference
  Section 3.4.1. Basic customization
  Section 3.4.3. Customizing class creation

Most of the content there is way beyond my current understanding, but I came up
with the following code, which seems to work:

class MyClass_2(object):
def __new__(self, condition):
if condition:
return object.__new__(self)
else:
return None

condition = 0
my_object_2 = MyClass_2(condition)
print my_object_2
condition = 1
my_object_2 = MyClass_2(condition)
print my_object_2

Can anyone see any technical or style issues with that? Or
alternatively reassure me that it is completely ok?
Thanks.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] A class that instantiates conditionally ?

2011-03-02 Thread Steven D'Aprano

Alan Gauld wrote:


"David"  wrote


clever enough to refuse to instantiate itself if a necessary condition
is not met.




class MyClass_2(object):
def __new__(self, condition):
 if condition:
   return object.__new__(self)
 else:
   return None


Thats pretty much how I'd do it.


By convention, the name of the first argument to __new__ is cls, not 
self, because it is bound to the class object itself (MyClass_2 in this 
example) rather than the instance. The instance doesn't yet exist, so 
that's not surprising!




--
Steven

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] A class that instantiates conditionally ?

2011-03-01 Thread Alan Gauld


"Hugo Arts"  wrote


Side question: Any reason why you'd raise the exception from __new__
rather than __init__? If you want to return None, then yeah I can 
see
why you'd have to use __new__, but would there be any reason you 
can't

or shouldn't simply raise an exception from __init__?


Because by the  time you get to init you have already created
the instance. If you really want to avoid creating an instance it
needs to be in new.


Alan G


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] A class that instantiates conditionally ?

2011-03-01 Thread Hugo Arts
On Tue, Mar 1, 2011 at 5:35 PM, Alan Gauld  wrote:
>
> "David"  wrote
>
>> clever enough to refuse to instantiate itself if a necessary condition
>> is not met.
>
> Oops, sent too soon.
>
> I meant to add that you should realize that the implication of your
> design is that the user of the class now has to check each object
> to see if it is a valid reference or None. You could raise an exception
> instead of returning None which allows a try/except style...
>
> This extra overhead is one reason these kinds of "clever" tricks
> are usually avoided. A valid object with null content is often
> preferrable, or a singleton style pattern. But occasionally your
> style is needed, just be aware of the extra overhead you
> introduce by using it.
>

Side question: Any reason why you'd raise the exception from __new__
rather than __init__? If you want to return None, then yeah I can see
why you'd have to use __new__, but would there be any reason you can't
or shouldn't simply raise an exception from __init__?
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] A class that instantiates conditionally ?

2011-03-01 Thread Alan Gauld


"David"  wrote

clever enough to refuse to instantiate itself if a necessary 
condition

is not met.


Oops, sent too soon.

I meant to add that you should realize that the implication of your
design is that the user of the class now has to check each object
to see if it is a valid reference or None. You could raise an 
exception

instead of returning None which allows a try/except style...

This extra overhead is one reason these kinds of "clever" tricks
are usually avoided. A valid object with null content is often
preferrable, or a singleton style pattern. But occasionally your
style is needed, just be aware of the extra overhead you
introduce by using it.

HTH,


--
Alan Gauld
Author of the Learn to Program web site
http://www.alan-g.me.uk/


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] A class that instantiates conditionally ?

2011-03-01 Thread Alan Gauld


"David"  wrote

clever enough to refuse to instantiate itself if a necessary 
condition

is not met.




class MyClass_2(object):
def __new__(self, condition):
 if condition:
   return object.__new__(self)
 else:
   return None


Thats pretty much how I'd do it.

Alan G. 



___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] A class that instantiates conditionally ?

2011-02-28 Thread David
I have an idea that might clean up my code slightly, if I can make one
of my classes
clever enough to refuse to instantiate itself if a necessary condition
is not met.

Below I propose some example code that seems to achieve this, and I am
asking here
for feedback on it, because I have not written much python. So I might be doing
something unwise due to fiddling with things I don't totally understand.

My aim is that instead of writing this:

class MyClass:
pass

condition = 0

if condition:
my_object = MyClass()
else:
my_object = None

I could instead write this:

class MyClass_2:
# put the if-test here inside the class

my_object_2 = MyClass_2(condition)

to achieve the goal that (my_object_2 == None) when (condition == False).

I read the (ver 2.6) Python Language Reference
 Section 3.4.1. Basic customization
 Section 3.4.3. Customizing class creation

Most of the content there is way beyond my current understanding, but I came up
with the following code, which seems to work:

class MyClass_2(object):
def __new__(self, condition):
if condition:
return object.__new__(self)
else:
return None

condition = 0
my_object_2 = MyClass_2(condition)
print my_object_2
condition = 1
my_object_2 = MyClass_2(condition)
print my_object_2

Can anyone see any technical or style issues with that? Or
alternatively reassure me that it is completely ok?
Thanks.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor