Oh my! I couldn't disagree more strongly! I think the above is totally
incorrect.
It was intended to help the OP out of the mental hole he finds himself in.
Most of the classes I use fall directly into such a classification - they are
useless until an instance is created. And I would be so bold as to say that
_all_ gui classes are like that.
This is the pattern I am talking about:
class thing(object):
def __init__(self,foo,bar):
stuff to do things with foo and bar,
creating or modifying attributes of
the instance.
def somemethod(self,baz,bling):
instance method to do further operations on
the attributes of the instance
Now kindly explain to me how a class like that is usefull before an instance
of it is created, and I might agree with you that what I said is "totally
incorrect"
8< --trivial examples showing that there is something there ------------
Classes are themselves instances of their metaclass. By default, classes
have a metaclass of type, but you can easily change that. Metaclass
programming is advanced but very powerful.
Because classes are themselves objects, you can (with a bit of metaclass
jiggery-pokery) make them do all sorts of interesting things. For
instance, huge amounts of effort are often put into creating a Singleton
class, a class that has a single instance. Well, okay... but why not just
use the class object itself, instead of an instance? There's already one
of those, and you can't (easily) make a copy of it, and even if you did,
it would be an independent class. Instead of this:
singleton = SingletonClass(args)
do_something_with(singleton)
just do this:
do_something_with(SingletonClass)
Of course SingletonClass needs to be designed to work that way, which
will probably need some metaclass magic. It would be interesting to see
which requires less effort.
*nods* yes this would make sense - but it is not quite what either the OP or I
was on about.
When it comes to built-in classes (types), I often use the class object
itself as an object. E.g. I might do something like this:
def convert(seq):
t = type(seq) # remember the original type
result = process(seq) # always produces a list
if t is list:
return result # don't bother making a copy of the result
elif t is str or t is unicode:
empty = t()
return empty.join(result)
else:
return t(result) # return the original type
nice. now try doing it with object:
thing = object()
After that, thing will exist, but it is a bit like write only memory -
completely useless, until you have done some more work with it.
Completely no. You may have missed the examples I've given, but the
problems the Original Poster were having had nothing to do with recursion.
The yes was in there to make the man feel a bit better, and because from where
he stood, it _was_ the recursion that did him in. : - )
That is incorrect. What's going on is more subtle.
Right - I can see that you are reading that to mean that there must be an
instance. That is not what I intended to bring across. I was talking about
the lack of a reference that is his original problem, which he only
encountered with recursion.
... def function(x):
... print "Calling function with argument %s" % x
... function(None)
... function(1)
... function(function)
...
Calling function with argument None
Calling function with argument 1
<class __main__.Demo at 0xb7d4e0ec>
two points:
Of what earthly use is a bare class like that - except possibly as a container
for all the good stuff those functions produced out of nothing? - You might
as well use a list, or better a dict, to keep the results of such functions,
unless the functions are procedures, doing things by side effect - and if
that is the case, why bother putting them in a class?
Secondly:
Now what you have done is carefully avoided the OP's original problem, which
arises when the function in the class is called, and tries to call itself at
the time of execution of the class suite, and fails, for the reasons so
nicely explained by a lot of people. So the OP had a point when he
complained that python does not like recursion, because, until he understands
what is happening, the simplest theory that fits his observed facts is that
the failure is caused by the recursion. - a completely rational conclusion
based on Occam's razor. It just happens to be wrong in this case. This was
the source for my "Yes" above.
This should also work for the OP - I cannot recall if it has been shown:
class Demo(object):
def fact(x,f):
if x < 2:
return 1
else:
return x*f(x-1,f)
thing = fact(42,fact)
I still think it is stupid, though - thing should simply be set to
1405006117752879898543142606244511569936384000000000L
and that would be the end of it for this use case, without the bother of a
function and the concomitant waste of time.
- Hendrik