Skip to content

Instantly share code, notes, and snippets.

Last active January 5, 2022 17:43
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save devforfu/1de5cecb96f92bd99ed595de7cdb7907 to your computer and use it in GitHub Desktop.
Simple example of __new__ method usage
An example of usage of __new__ magic method to implement dynamic computational
logic dispatching.
For more information see:
import abc
class TemperatureConverter(metaclass=abc.ABCMeta):
Base class of temperature converters which supports dynamic substitution
of implementations.
symbol = 'K'
def __new__(cls, convert_to='celsius'):
if issubclass(cls, TemperatureConverter):
if convert_to == 'celsius':
cls = _CelsiusConverter
elif convert_to == 'fahrenheit':
cls = _FahrenheitConverter
raise ValueError('unexpected converter: %s' % convert_to)
return object.__new__(cls)
def convert(self, value):
Converts temperature from Kelvin degrees into format defined by
concrete implementation.
return self._convert(value)
def format(self, value):
return '%.2f (%s)' % (self.convert(value), self.symbol)
def check_value(value):
if value < 0:
raise ValueError('temperature should be provided in Kelvin degrees')
def name(self):
return self.__class__.__name__.strip('_')
def _convert(self, value):
raise NotImplementedError()
class _CelsiusConverter(TemperatureConverter):
Concrete implementation of temperature converted which converts from Kelvin
into Celsius degrees.
symbol = '°C'
def _convert(self, value):
return value - 273.15
class _FahrenheitConverter:
Concrete implementation of temperature converter which converts from Kelvin
into Fahrenheit degrees.
Note that this class does not directly inherit base class, but is
registered as derived class using ABCMeta.register method. Though in this
case, there is no a default implementation of `format` method and `name`
symbol = '°F'
def _convert(self, value):
return value * 9./5 - 459.67
def format(self, value):
return '%.2f (%s)' % (self._convert(value), self.symbol)
def name(self):
return 'FahrenheitConverter'
def main():
converters = [
for name in ('celsius', 'fahrenheit')]
temperature = 300
for converter in converters:
string = converter.format(temperature)
print('%s converted %sK temperature into: %s' % (, temperature, string
if __name__ == '__main__':
Copy link

I just discovered your blog and instantly became a fan. I did not see a subscription / notification option :-(. I hope you keep enlightening us with your experience. One question: I am looking at the snippet that precedes this code in your blog post, and all I can think is: "This looks like Java". But I did not see this object replicated in the actual code, perhaps because of my relative inexperience and unfamiliarity with Java - or whatever this is in Python. Can you explain a little more, and why that choice, particularly? Thanks!

Copy link

devforfu commented Jan 5, 2022

@MalikRumi thank you so much for appreciation! I'm sorry for the late response, didn't see that a comment was left on this gist. Yes, you're right, it is not a "real" Python code but a pseudocode. Or more exactly, it was inspired by Swift. (Actually, I think that it may be even a real-working Swift code if I didn't do a typo there...) I played around with that language back then, and really liked it. So decided to include some abstract example there using some statically typed object-oriented language that I knew. Hope that helps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment