Hi all. I’m a long-time Perl developer, porting some stuff to Python. I need a constructor or factory to be able to return a subclass, based on the database type in a connection object passed in ( there are a LOT of other things also being passed in ). I have the detection of the database type working ( kind of ). In Perl, I’d then just concatenate things, like:
sub generate_subclass {
my $connection = shift; # pull the connection object *ONLY*
my $database_type = get_database_type( $connection );
my $target_class_type = $database_type . 'myclass';
return $target_class_type->new( $connection , @_ ); # pass all other args into target constructor
}
Is there a way to instantiate a class based on a variable, as in the “return” line, above?
By Dan Kasak via Discussions on Python.org at 12Sep2022 06:52:
Hi all. I’m a long-time Perl developer, porting some stuff to Python. I
need a constructor or factory to be able to return a subclass, based on
the database type in a connection object passed in […]
I wrote one of these just today!
def TypedKeyClass(key_type, superclass, name=None):
''' Factory to create a new mapping class subclassing
`(TypedKeyMixin,superclass)` which checks that keys are of type
`key_type`.
'''
class TypedKeyMapping(TypedKeyMixin, superclass):
def __init__(self, *a, **kw):
''' Initialise the `TypedKeyDict`. The first positional parameter
is the type for keys.
'''
TypedKeyMixin.__init__(self, key_type)
superclass.__init__(self, *a, **kw)
if not all(map(lambda key: type(key) is key_type, self.keys())):
raise TypeError("all keys must be of type %s" % (key_type,))
if name is None:
name = f'{key_type.__name__}Typed{superclass.__name__}'
TypedKeyMapping.__name__ = name
TypedKeyMapping.__doc__ = stripped_dedent(
f'''
Subclass of `{superclass.__name__}` which ensures that its
keys are of type `{key_type.__name__}` using `TypedKeyMixin`.
'''
)
return TypedKeyMapping
StrKeyedDict = TypedKeyClass(str, dict, name='StrKeyedDict')
UUIDKeyedDict = TypedKeyClass(UUID, dict, name='UUIDKeyedDict')
The basic deal is to write a function which defines a class which uses
the function parameter values in its definition.
The above defines the factory function, and then makes two convenience
classes using the factory.
So we make a local class named TypedKeyMapping. Then there’s a bit of
boilerplate to set its name (there’s an automatic default) and its
docstring, then we return it.
Sorry, I can’t read Perl well enough to understand what your code does
Could you maybe describe it in pseudo-code or English?
Does the subclass already exist, or do you need to create it on the fly?
class Parrot: pass
class RedParrot(Parrot): pass
def factory(colour):
if colour == 'red':
# Subclass already exists.
return RedParrot()
elif colour == 'blue:
# Create subclass on the fly. (Warning: this is
# wasteful of memory and may be confusing.)
class BlueParrot(Parrot):
pass
return BlueParrot()
else:
return Parrot()
Otherwise I’m not sure I understand your question.