Skip to content

Instantly share code, notes, and snippets.

@theavey
Last active December 11, 2018 16:19
Show Gist options
  • Save theavey/bddb611fd5d846de932263ac63e7d57c to your computer and use it in GitHub Desktop.
Save theavey/bddb611fd5d846de932263ac63e7d57c to your computer and use it in GitHub Desktop.
Use a metaclass to self-register subclasses to easily instatiate new objects and use an abstract base class
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"from abc import abstractmethod, ABCMeta"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
"class DynamicsMeta(ABCMeta):\n",
" def __init__(cls, name, bases, dct):\n",
" if not hasattr(cls, 'registry'):\n",
" cls.registry = {}\n",
" else:\n",
" dyn_id = name.lower()\n",
" cls.registry[dyn_id] = cls\n",
" super(DynamicsMeta, cls).__init__(name, bases, dct)"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"class Dynamics(metaclass=DynamicsMeta):\n",
" \n",
" @abstractmethod\n",
" def density_matrix(self):\n",
" pass\n",
" \n",
" @abstractmethod\n",
" def time_step(self):\n",
" pass\n",
" \n",
" @classmethod\n",
" def make_new(self, kind, *args, **kwargs):\n",
" return self.registry[kind](*args, **kwargs)"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
"class PLDM(Dynamics):\n",
" def __init__(self, *args, **kwargs):\n",
" self.args = args\n",
" self.kwargs = kwargs\n",
" \n",
" def density_matrix(self):\n",
" return 'PLDM density matrix'\n",
" \n",
" def time_step(self):\n",
" return 'Advanced PLDM time'\n",
"\n",
"class IPLDM(Dynamics):\n",
" def __init__(self, *args, **kwargs):\n",
" self.args = args\n",
" self.kwargs = kwargs\n",
" \n",
" def density_matrix(self):\n",
" return 'IPLDM density matrix'\n",
" \n",
" def time_step(self):\n",
" return 'Advanced IPLDM time'\n",
"\n",
"class Broken(Dynamics):\n",
" def __init__(self, *args, **kwargs):\n",
" self.args = args\n",
" self.kwargs = kwargs\n",
" \n",
" def density_matrix(self):\n",
" return 'Broken density matrix'\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"PLDM density matrix\n"
]
}
],
"source": [
"pldm = Dynamics.make_new('pldm')\n",
"print(pldm.density_matrix())"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"ename": "TypeError",
"evalue": "Can't instantiate abstract class Broken with abstract methods time_step",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-23-13055d4f9720>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mbroke\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mDynamics\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmake_new\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'broken'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m<ipython-input-20-942ed3c02c9c>\u001b[0m in \u001b[0;36mmake_new\u001b[0;34m(self, kind, *args, **kwargs)\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0mclassmethod\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mmake_new\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkind\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 13\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mregistry\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mkind\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m: Can't instantiate abstract class Broken with abstract methods time_step"
]
}
],
"source": [
"broke = Dynamics.make_new('broken')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment