Anonymous Classes

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Lachlan Gunn

    Anonymous Classes

    Hello.

    I have a library (SQLObject) that stores data as class variables. I would
    like to set a class variable in a certain context, specific to a certain
    instance of an object. This would require some sort of anonymous class. I
    have attempted to use the following code to set the connection string:

    | class SQLStorage:
    | def __init__(self, c, debug = False):
    | config = StorageConfigur ation(c)
    |
    | connection = sqlobject.conne ctionForURI(con fig.databaseStr ing)
    | if debug:
    | connection.debu g = True
    |
    | # I don't know whether this is right. My belief is that we can
    | # subclass each table and use _connection on them.
    | class newDatum(DatumT able):
    | _connection = connection
    |
    | class newMetadatum(Me tadatumTable):
    | _connection = connection
    |
    | class newChecksum(Che cksumTable):
    | _connection = connection
    |
    | self.__SQLDatum = newDatum
    | self.__SQLMetad atum = newMetadatum
    | self.__SQLCheck sum = newChecksum

    This does not work; Python complains that the classes already exist when
    SQLObject is instantiated for a second time. This has led me to try
    instantiating a subclass using DatumTable.__cl ass__ and friends, but this
    requires setting a class name, which, again, limits me to a single
    instance. I *could* have a counter that appends a number to each class
    name, but that's a fairly ugly solution; is it possible to create an
    anonymous class in Python?

    Thanks,
    Lachlan.
  • Bruno Desthuilliers

    #2
    Re: Anonymous Classes

    Lachlan Gunn a écrit :
    Hello.
    >
    I have a library (SQLObject) that stores data as class variables. I would
    like to set a class variable in a certain context, specific to a certain
    instance of an object. This would require some sort of anonymous class. I
    have attempted to use the following code to set the connection string:
    >
    | class SQLStorage:
    You probably want:

    class SQLStorage(obje ct):
    | def __init__(self, c, debug = False):
    | config = StorageConfigur ation(c)
    |
    | connection = sqlobject.conne ctionForURI(con fig.databaseStr ing)
    | if debug:
    | connection.debu g = True
    |
    | # I don't know whether this is right. My belief is that we can
    | # subclass each table and use _connection on them.
    | class newDatum(DatumT able):
    | _connection = connection
    |
    | class newMetadatum(Me tadatumTable):
    | _connection = connection
    |
    | class newChecksum(Che cksumTable):
    | _connection = connection
    |
    | self.__SQLDatum = newDatum
    | self.__SQLMetad atum = newMetadatum
    | self.__SQLCheck sum = newChecksum
    Are you sure you need name mangling here ?
    This does not work; Python complains that the classes already exist when
    SQLObject is instantiated for a second time. This has led me to try
    instantiating a subclass using DatumTable.__cl ass__ and friends, but this
    requires setting a class name, which, again, limits me to a single
    instance. I *could* have a counter that appends a number to each class
    name, but that's a fairly ugly solution; is it possible to create an
    anonymous class in Python?
    Yes. Using type() :

    Help on class type in module __builtin__:

    class type(object)
    | type(object) -the object's type
    | type(name, bases, dict) -a new type

    >>class Toto(object):
    .... pass
    ....
    >>class Tutu(object):
    .... def __init__(self, what):
    .... self._toto = type('Autototo' , (Toto,), dict(_what=what ))
    ....
    >>t = Tutu(42)
    >>t._toto
    <class '__main__.Autot oto'>
    >>t._toto._wh at
    42
    >>t._toto()
    <__main__.Autot oto object at 0xb7c3806c>
    >>t2 = Tutu(1138)
    >>t2._toto
    <class '__main__.Autot oto'>
    >>t2._toto._wha t
    1138

    Comment

    • Lachlan Gunn

      #3
      Re: Anonymous Classes

      Thanks for your help.

      After trying your suggestion for a while, I eventually realised that
      SQLObject was doing something funny in its metaclass that was causing the
      issue, which I got around by mangling the class names with a counter.

      Comment

      Working...