What do you call a class not intended to be instantiated

S

Steven D'Aprano

I have a class which is not intended to be instantiated. Instead of using
the class to creating an instance and then operate on it, I use the class
directly, with classmethods. Essentially, the class is used as a function
that keeps state from one call to the next.

The problem is that I don't know what to call such a thing! "Abstract
class" isn't right, because that implies that you should subclass the
class and then instantiate the subclasses.

What do you call such a class?
 
J

James Mills

Hi,

Wouldn't a normal class called State
suffice for storing state between calls ?
And ... Creating a state instance ?

For example:

class State(object):
"""State() -> new state object

Creates a new state object that is suitable
for holding different states of an application.
Usefull in state-machines.

The way this works is rather simple. You create a new
state object, and simply set the state. If the state
doesn't exist, it's added to it's internal data
structure. The reason this is done is so that
comparing states is consistent, and you can't just
compare with a non-existent state.
"""

def __init__(self):
"initializes x; see x.__class__.__doc__ for signature"

self._states = {}
self._next = 0

# Default States

self._add("START")
self._add("DONE")

def __repr__(self):
try:
return "<State: %s>" % self._state
except AttributeError:
return "<State: ???>"

def __str__(self):
return self._state

def __eq__(self, s):
return s in self._states and self._state == s

def __lt__(self, s):
return s in self._states and self._state == s and \
self._states < self._states[self._state]

def __gr__(self, s):
return s in self._states and self._state == s and \
self._states > self._states[self._state]

def _add(self, s):
self._states = self._next
self._next = self._next + 1

def set(self, s):
"""S.set(s) -> None

Set the current state to the specified state given by s,
adding it if it doesn't exist.
"""

if s not in self._states:
self._add(s)

self._state = s

cheers
James
 
S

Steven D'Aprano

Fixing top-posting.


[...]
Hi,

Wouldn't a normal class called State
suffice for storing state between calls ? And ... Creating a state
instance ?

For example:
[snip]

That's a rather big example for a rather small question.

Yes, a normal class would work in many cases. In this case, the class
itself is being produced by a factory function, and it's output is an
iterator. Having to call:

cls = factory()
instance = cls()
result = instance()

to get anything done seems excessive, even if you write it as a one-liner
result = factory()()().

I'm not wedded to the idea, there are alternatives (perhaps the factory
should instantiate the class and return that?) but I assume others have
used this design and have a name for it.
 
J

James Mills

I'm not wedded to the idea, there are alternatives (perhaps the factory
should instantiate the class and return that?) but I assume others have
used this design and have a name for it.

The problem is, I don't see why you're using a class
to store state in the first place.

cheers
James
 
B

bearophileHUGS

Steven D'Aprano:
I have a class which is not intended to be instantiated. Instead of using
the class to creating an instance and then operate on it, I use the class
directly, with classmethods. Essentially, the class is used as a function
that keeps state from one call to the next.

You may use a module too for that, with normal functions inside, plus
module variables that keep the state. Modules can't be instantiated, I
think.

Bye,
bearophile
 
J

James Mills

I call it an obvious misuse and misunderstanding of why you'd use a class in
the first place. Either create an instance and not make these things
classmethods or just share the stuff in a module-level set of variables. But
the instantiating is the best options. Your class attributes might not be
globals, but you're still using global state and you should avoid it where
you can.

I concur. Use a _proper_ state object that you share
amongst your other objects. For instance, in many of
my systems and applications I write, I often have
an "Environment" instance, which is a container
object that holds other objects required by parts
of the system. Every other component/object in the
system that is instantiated recievees exactly one
instnace of thie "Environment" called, "env".

Accessing shared states amongst components/objects
within the system is as simple as this:

class Foo(object):

def __init__(self, env, *args, **kwargs):
self.env = env

def foo(self):
if self.env.some_state:
print "Do something useful"

env = Environment()
foo = Foo(env)
foo.foo()

cheers
James
 
A

Aaron \Castironpi\ Brady

Fixing top-posting.

I have a class which is not intended to be instantiated. Instead of
using the class to creating an instance and then operate on it, I use
the class directly, with classmethods. Essentially, the class is used
as a function that keeps state from one call to the next.
[...]

Wouldn't a normal class called State
suffice for storing state between calls ? And ... Creating a state
instance ?
For example:

[snip]

That's a rather big example for a rather small question.

Yes, a normal class would work in many cases. In this case, the class
itself is being produced by a factory function, and it's output is an
iterator. Having to call:

cls = factory()
instance = cls()
result = instance()

to get anything done seems excessive, even if you write it as a one-liner
result = factory()()().

I'm not wedded to the idea, there are alternatives (perhaps the factory
should instantiate the class and return that?) but I assume others have
used this design and have a name for it.

Do you want anything from it that a dictionary doesn't have, besides
the dot-member access?
 
R

Rhamphoryncus

I have a class which is not intended to be instantiated. Instead of using
the class to creating an instance and then operate on it, I use the class
directly, with classmethods. Essentially, the class is used as a function
that keeps state from one call to the next.

The problem is that I don't know what to call such a thing! "Abstract
class" isn't right, because that implies that you should subclass the
class and then instantiate the subclasses.

What do you call such a class?

If defining it as a normal class, it is a namespace. Just a way to
cluster multiple globals into a single global. The borg pattern does
the same thing, but with a 12 page treatise on why it shouldn't do
exactly what it's doing.

If using a factory you should probably be using an instance; the fact
that your instance is a class is a relatively minor implementation
detail. Indeed, the only reason to have a class is to have your
methods bound when looked up.

You might want a metaclass to cripple it, preventing subclassing and
whatnot. *shrug*.
 
B

Bruno Desthuilliers

Steven D'Aprano a écrit :
I have a class which is not intended to be instantiated. Instead of using
the class to creating an instance and then operate on it, I use the class
directly, with classmethods. Essentially, the class is used as a function
that keeps state from one call to the next.

The problem is that I don't know what to call such a thing! "Abstract
class" isn't right, because that implies that you should subclass the
class and then instantiate the subclasses.

What do you call such a class?

<nitpick>
Err... A possible design smell ?-)
</nitpick>


More seriously: this looks quite like a singleton, which in Python is
usually implemented way more simply using a module and plain functions.

Do you have a use case for specializing this class ?
 
S

Steven D'Aprano

I concur. Use a _proper_ state object that you share amongst your other
objects.


But that's precisely what I want to avoid: I don't want the objects to
share *any* state, not even their class. I'm not trying for a Borg or
Singleton: the user can call the factory as many times as they want, but
the objects returned shouldn't share any state. I don't know if what I
want has a name. Judging from people's reactions, I'd say probably not.

(For the pedantic: the "instances" will all have the same methods, but
I'm not including methods as state.)


For instance, in many of my systems and applications I write, I
often have an "Environment" instance, which is a container object that
holds other objects required by parts of the system. Every other
component/object in the system that is instantiated recievees exactly
one instnace of thie "Environment" called, "env".

Accessing shared states amongst components/objects within the system is
as simple as this:

class Foo(object):

def __init__(self, env, *args, **kwargs):
self.env = env

def foo(self):
if self.env.some_state:
print "Do something useful"

Seems wasteful to me. Why give every instance it's own instance-level
reference to the shared object? Why not make env a class attribute, set
once, instead of every time you instantiate the class?


class Foo(object):
env = env

But in any case, this is not the behaviour I want. It's the opposite of
the behaviour I want. I don't want the objects to share state. I'm not
exactly sure what I said that has given so many people the impression
that I do.
 
S

Steven D'Aprano

Steven D'Aprano a écrit :
<nitpick>
Err... A possible design smell ?-)
</nitpick>


More seriously: this looks quite like a singleton, which in Python is
usually implemented way more simply using a module and plain functions.


I really don't know why everyone thinks I want a Singleton. I want to
uncouple objects, not increase the coupling.


Consider a factory function:

def factory(x): # a toy example
alist = [x]
def foo():
return alist
return foo


Now suppose we "instantiate" the factory (for lack of a better term):

Even though f1 and f2 have the same behaviour, they are obviously not the
same object. And although both return a list [0], it is not the same list:
f1() == f2() == [0] True
f1() is f2()
False


They have a (very little) amount of state, which is *not* shared:
L = f1()
L.append(1)
f1() [0, 1]
f2()
[0]


But there's only a limited amount of state that functions carry around. I
can give them more state like this:

but it isn't good enough if the function needs to refer to it's own
state, because functions can only refer to themselves by name and the
factory can't know what name the function will be bound to.

As far as I know, the only objects that know how to refer to themselves
no matter what name they have are classes and instances. And instances
share at least some state, by virtue of having the same class.

(Pedants will argue that classes also share state, by virtue of having
the same metaclass. Maybe so, but that's at a deep enough level that I
don't care.)

I'm now leaning towards just having factory() instantiate the class and
return the instance, instead of having to do metaclass chicanery. Because
the class is built anew each time by the factory, two such instances
aren't actually sharing the same class. I think that will reduce
confusion all round (including mine!).

Hopefully now that I've explained what I want in more detail, it won't
seem so bizarre. Factory functions do it all the time. Is there a name
for this pattern?

Thanks to everyone who commented, your comments helped me reason out a
better alternative to what I first suggested.
 
J

James Mills

On 22 Sep 2008 09:07:43 GMT, Steven D'Aprano
But that's precisely what I want to avoid: I don't want the objects to
share *any* state, not even their class. I'm not trying for a Borg or
Singleton: the user can call the factory as many times as they want, but
the objects returned shouldn't share any state. I don't know if what I
want has a name. Judging from people's reactions, I'd say probably not.

Snce when are "users" ever involved
in programming problems or programming
languages ?

--JamesMills
 
B

Bruno Desthuilliers

Steven D'Aprano a écrit :
I really don't know why everyone thinks I want a Singleton.

May I quote you ?
"""
Instead of using the class to creating an instance and then operate on
it, I use the class directly, with classmethods. Essentially, the class
is used as a function that keeps state from one call to the next.
"""
I want to
uncouple objects, not increase the coupling.


Consider a factory function:

def factory(x): # a toy example
alist = [x]
def foo():
return alist
return foo


Now suppose we "instantiate" the factory (for lack of a better term):

Even though f1 and f2 have the same behaviour, they are obviously not the
same object. And although both return a list [0], it is not the same list:
f1() == f2() == [0] True
f1() is f2()
False
>

They have a (very little) amount of state, which is *not* shared:
L = f1()
L.append(1)
f1() [0, 1]
f2()
[0]


But there's only a limited amount of state that functions carry around. I
can give them more state like this:

but it isn't good enough if the function needs to refer to it's own
state, because functions can only refer to themselves by name and the
factory can't know what name the function will be bound to.

Then define your own callable type.
As far as I know, the only objects that know how to refer to themselves
no matter what name they have are classes and instances. And instances
share at least some state, by virtue of having the same class.

Is that a problem in your use case, and if so, why ???
(Pedants will argue that classes also share state, by virtue of having
the same metaclass. Maybe so, but that's at a deep enough level that I
don't care.)

I'm now leaning towards just having factory() instantiate the class and
return the instance, instead of having to do metaclass chicanery. Because
the class is built anew each time by the factory, two such instances
aren't actually sharing the same class. I think that will reduce
confusion all round (including mine!).

Hopefully now that I've explained what I want in more detail, it won't
seem so bizarre. Factory functions do it all the time. Is there a name
for this pattern?

Thanks to everyone who commented, your comments helped me reason out a
better alternative to what I first suggested.

Glad to know you found something helpful in all these answers, but as
far as I'm concerned, I'm afraid I still fail to understand what exactly
you're after...
 
A

Arnaud Delobelle

but it isn't good enough if the function needs to refer to it's own
state, because functions can only refer to themselves by name and the
factory can't know what name the function will be bound to.

As far as I know, the only objects that know how to refer to themselves
no matter what name they have are classes and instances. And instances
share at least some state, by virtue of having the same class.

Here is a simple way to make a function able to refer to its own
state:

def bindfunction(f):
def bound_f(*args, **kwargs):
return f(bound_f, *args, **kwargs)
bound_f.__name__ = f.__name__
return bound_f
.... def foo(me, x):
.... me.attr.append(x)
.... return me.attr
....
foo.attr = []
foo(3) [3]
foo(5) [3, 5]
 
T

Tim Rowe

2008/9/22 Bruno Desthuilliers said:
Ok, then the simple solution is to implement a callable type (__call__
method), possibly with appropriate support for the descriptor protocol if
it's meant to be usable as a method.

Yes -- and instantiate the thing and keep the state in the instance,
rather than keeping the state in the class, so that it's possible to
safely have more than one of them if a later design change calls for
it (probably what led people off onto the sidetrack of thinking a
singleton was called for). That's the classic way of implementing a
"class [to be] used as a function".
 
A

Aaron \Castironpi\ Brady

Ok, then the simple solution is to implement a callable type (__call__
method), possibly with appropriate support for the descriptor protocol if
it's meant to be usable as a method.

Yes -- and instantiate the thing and keep the state in the instance,
rather than keeping the state in the class, so that it's possible to
safely have more than one of them if a later design change calls for
it (probably what led people off onto the sidetrack of thinking a
singleton was called for).  That's the classic way of implementing a
"class [to be] used as a function".

I think you are either looking for a class that has a generator, or a
generator that has a reference to itself.
 
M

Matimus

I have a class which is not intended to be instantiated. Instead of using
the class to creating an instance and then operate on it, I use the class
directly, with classmethods. Essentially, the class is used as a function
that keeps state from one call to the next.

The problem is that I don't know what to call such a thing! "Abstract
class" isn't right, because that implies that you should subclass the
class and then instantiate the subclasses.

What do you call such a class?

It actually sounds like you are doing something similar to the
monostate pattern. In Java the monostate pattern is usually
implemented by creating a class that only has static functions and
variables. You _can_ instantiate it, but every instance will share the
same state. In that way it is very similar to the Singleton pattern
(http://en.wikipedia.org/wiki/Singleton_pattern).

In Python I haven't found a need for monostate, since you can override
__new__ and return exactly the same instance. However, you you wanted
to be able to inherit a monostate object and share some of the state
between the class and subclass it might still be useful.

Perhaps if you post some example code?

Matt
 
T

Terry Reedy

Steven said:
Consider a factory function:

def factory(x): # a toy example
alist = [x]
def foo():
return alist
return foo


Now suppose we "instantiate" the factory (for lack of a better term):

Your factory is returning closures. This is the functional equivalent
of a class returning instances.

class factory(object):
def __init__(self, x):
self.alist = [x]
def __call__(self):
return self.alist
Even though f1 and f2 have the same behaviour, they are obviously not the
same object. And although both return a list [0], it is not the same list:
f1() == f2() == [0] True
f1() is f2()
False

same results
They have a (very little) amount of state, which is *not* shared:
L = f1()
L.append(1)
f1() [0, 1]
f2()
[0]

same results
But there's only a limited amount of state that functions carry around.

That is why Python has class statements.
> And instances share at least some state, by virtue of having the same
class.

If the only class attributes are methods and you do mutate the class,
then the fact that f1.__class__ is f2.__class__ is not really shared state.

[from a later post]
>But that's precisely what I want to avoid: I don't want the objects to
share *any* state, not even their class.

Unless you can show how sharing an immutable __class__ attribute is an
actual impediment, this strike me as artificial pedantry and unnecessary
self handcuffing. And you obviously can make that attribute effectively
immutable by ignoring it and also not changing the class itself. It is
just internal, implementation-defined bookkeeping.

The identity of immutable objects is irrelevant. If part of your
'unshared state' for each instance were a string, and two instances
happened to have the same string value, would you be upset because the
interpreter happened to use the same string object instead of two string
objects with the same value? Ditto for numbers, tuples, and so on.

Terry Jan Reedy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top