467,892 Members | 1,894 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 467,892 developers. It's quick & easy.

Class instantiation question

Ok, say I have a class MyClass and an __init__(self,
a, b) Say that a and b are required to be integers
for example. So my init looks like:

__init__(self, a, b):
try:
self.one = int(a)
self.two = int(b)
except ValueError:
#nice error message here
return None

I have even tried a similar example with if-else
instead of try-except, but no matter what if I call

thisInstance = MyClass(3, "somestring")

it will set self.one to 3 and self.two will be
uninitialised. The behavior I am hoping for, is that
thisInstance is not created instead(or is None). How
do I get the behavior I am looking for?

Thanks in advance,
Todd

__________________________________
Do you Yahoo!?
The New Yahoo! Shopping - with improved product search
http://shopping.yahoo.com

Jul 18 '05 #1
  • viewed: 1309
Share:
5 Replies
Todd Johnson wrote:
Ok, say I have a class MyClass and an __init__(self,
a, b) Say that a and b are required to be integers
for example. So my init looks like:

__init__(self, a, b):
try:
self.one = int(a)
self.two = int(b)
except ValueError:
#nice error message here
return None

I have even tried a similar example with if-else
instead of try-except, but no matter what if I call

thisInstance = MyClass(3, "somestring")

it will set self.one to 3 and self.two will be
uninitialised. The behavior I am hoping for, is that
thisInstance is not created instead(or is None). How
do I get the behavior I am looking for?

Thanks in advance,
Todd


If I'm correct, __init__ method is somewhat different from what you
expect: it *doesn't* return values (None is just a fake return value).
Actually MyClass(...) proceeds more or less in the following way:

1) create an object
2) call __init__ with parameters passed
3) return the object's reference.

Therefore, you cannot prevent object creation in __init__. You can only
throw an exception.

Actually, I see no reason to use if/then instead try/except or maybe
even simple self.one = int(a) (that will throw if anythins goes wrong),
but if you want, for example, to create another object depending on
parameters passed, take a look at __new__ method.

regards,
anton.

Jul 18 '05 #2
Todd Johnson wrote:
Ok, say I have a class MyClass and an __init__(self,
a, b) Say that a and b are required to be integers
for example. So my init looks like:

__init__(self, a, b):
try:
self.one = int(a)
self.two = int(b)
except ValueError:
#nice error message here
return None

I have even tried a similar example with if-else
instead of try-except, but no matter what if I call

thisInstance = MyClass(3, "somestring")

it will set self.one to 3 and self.two will be
uninitialised. The behavior I am hoping for, is that
thisInstance is not created instead(or is None). How
do I get the behavior I am looking for?

1. I highly recommend you rethink your programming. Are you planning
to handle the error in the function that called the MyClass
contructor? In other words, are you doing something like this:

def some_function(a,b):
thisInstance = MyClass(a,b)
if thisInstance is None:
handle_error()
else:
do_something_useful(thisInstance)

If so, you are not taking full advantage of the exception handling
mechanism. The best way to do it is like this:

def some_function(a,b):
try:
thisInstance = MyClass(a,b)
except ValueError:
handler_error()
else:
do_something_useful(thisInstance)

As always, a larger code snippet can help us help you with that, if
you wish.
2. If you're sure the behavior you want is to return None if a or b is
not an integer, then I recommned you use a factory function:

def my_class_maker(a,b):
try:
return MyClass(a,b)
except ValueError:
return None
--
CARL BANKS http://www.aerojockey.com/software

As the newest Lady Turnpot descended into the kitchen wrapped only in
her celery-green dressing gown, her creamy bosom rising and falling
like a temperamental souffle, her tart mouth pursed in distaste, the
sous-chef whispered to the scullery boy, "I don't know what to make of
her."
--Laurel Fortuner, Montendre, France
1992 Bulwer-Lytton Fiction Contest Winner
Jul 18 '05 #3
Todd Johnson wrote:
Ok, say I have a class MyClass and an __init__(self,
a, b) Say that a and b are required to be integers
for example. So my init looks like:

__init__(self, a, b):
try:
self.one = int(a)
self.two = int(b)
except ValueError:
#nice error message here
return None

I have even tried a similar example with if-else
instead of try-except, but no matter what if I call

thisInstance = MyClass(3, "somestring")

it will set self.one to 3 and self.two will be
uninitialised. The behavior I am hoping for, is that
thisInstance is not created instead(or is None). How
do I get the behavior I am looking for?


As far as I know, the only way to prevent __init__ from creating an
instance is for __init__ to raise an exception which is NOT caught and
handled within __init__. In your example, I think simply doing

class MyClass(self, a, b):
def __init__(self, a, b):
self.one = int(a)
self.two = int(b)

without the try...except block should do it. Then the calling code can
handle the ValueError appropriately.

David

Jul 18 '05 #4
Todd Johnson <ov**********@yahoo.com> wrote:
Ok, say I have a class MyClass and an __init__(self,
a, b) Say that a and b are required to be integers
for example. So my init looks like:

__init__(self, a, b):
try:
self.one = int(a)
self.two = int(b)
except ValueError:
#nice error message here
return None

I have even tried a similar example with if-else
instead of try-except, but no matter what if I call

thisInstance = MyClass(3, "somestring")

it will set self.one to 3 and self.two will be
uninitialised. The behavior I am hoping for, is that
thisInstance is not created instead(or is None). How
do I get the behavior I am looking for?


Here's one option:
class C: .... def __init__(self, a):
.... self.a = int(a)
.... c = C("hello") Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in __init__
ValueError: invalid literal for int(): hello

This also allows the following:
try: c = C("hello") .... except ValueError: c = None
.... print c None

If you really want initialization to return None instead of raising an
exception, you can override the __new__ method of a new-style class:
class C(object): .... def __new__(cls, a):
.... try: a = int(a)
.... except ValueError: return None
.... return object.__new__(cls, a)
.... def __init__(self, a):
.... self.a = a
.... c = C(1)
c.a 1 c = C("hello")
print c

None
Jul 18 '05 #5
Todd Johnson wrote:
Ok, say I have a class MyClass and an __init__(self,
a, b) Say that a and b are required to be integers
for example. So my init looks like:

__init__(self, a, b):
try:
self.one = int(a)
self.two = int(b)
except ValueError:
#nice error message here
return None
Any return statement in __init__ MUST return None (you
get an error otherwise). The job of __init__ is
preparing the self, which is already created.
I have even tried a similar example with if-else
instead of try-except, but no matter what if I call

thisInstance = MyClass(3, "somestring")

it will set self.one to 3 and self.two will be
uninitialised. The behavior I am hoping for, is that
thisInstance is not created instead(or is None). How
do I get the behavior I am looking for?


It's not a nice architecture AT ALL, but if you
insist you can have it -- as long at least as
class MyClass is new-style, e.g., subclasses
object -- by defining a __new__ method. The
process of calling a class can be summarized as:

[[ function equivalent to calling theclass with
positional args *a and named args **k ...: ]]

result = theclass.__new__(theclass, *a, **k)
if isinstance(result, theclass):
theclass.__init__(result, *a, **k)
return result

Normally, it's best to do all the work in __init__
and thus to inherit __new__ from type object.
But that's only for the NORMAL case, where one
assumes that calling theclass always either
raises / propagates an exception OR else returns
an instance of theclass. Since you deliberately
want to break this normal, expected rule --
having the call to theclass return None instead! --
you would need to define __new__.

For example:
class theclass(object):

def __new__(cls, a, b):
self = object.__new__(cls)
try:
self.one = int(a)
self.two = int(b)
except ValueError:
#nice error message here
return None
else:
return self

I would still recommend you to reconsider the
architecture you want. Why MUST you break all
normal Pythonic expectations of users of your
class...? If you must, Python lets you -- but
MUST you, really...?
Alex

Jul 18 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

7 posts views Thread by Drew McCormack | last post: by
3 posts views Thread by Patrick Guio | last post: by
10 posts views Thread by msnews.microsoft.com | last post: by
23 posts views Thread by mark.moore | last post: by
5 posts views Thread by Slant | last post: by
8 posts views Thread by Ole Nielsby | last post: by
4 posts views Thread by Devon Null | last post: by
reply views Thread by MrMoon | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.