Skip to content

Instantly share code, notes, and snippets.

@coburnw
Last active October 2, 2023 06:00
Show Gist options
  • Save coburnw/b98a1be29d5004787960c98ba715f160 to your computer and use it in GitHub Desktop.
Save coburnw/b98a1be29d5004787960c98ba715f160 to your computer and use it in GitHub Desktop.
Python Factory Using a Metaclass
# https://stackoverflow.com/a/5961102
# Note python3 has a different declaration than the so post
class ShapeFactory(type):
"""Shape Factory"""
def __call__(cls, selector, *args):
if cls is Shape:
# select a new object
print('factory build:', selector)
if selector == 'rectangle': return Rectangle(selector, *args)
if selector == 'triangle': return Triangle(selector, *args)
raise 'unrecognized shape'
# And initialize it
print('factory initialize:', selector)
return type.__call__(cls, selector, *args)
class Shape(metaclass=ShapeFactory):
"""Base Shape object. Contains factory and common methods"""
def __init__(self, selector, name):
"""
Args:
selector: The type of shape to build.
name: The second parameter.
Returns:
Nothing.
"""
print("shape init")
self.desc = name
self.edge_count = None
return
@property
def number_of_edges(self):
return self.edge_count
class Triangle(Shape):
def __init__(self, selector, name):
print("triangle init: {}".format(name))
super().__init__(selector, name)
self.edge_count = 3
return
@property
def name(self):
return 'Triangle'
class Rectangle(Shape):
def __init__(self, selector, name):
print("rectangle init: {}".format(name))
super().__init__(selector, name)
self.edge_count = 4
return
@property
def name(self):
return 'Rectangle'
if __name__ == '__main__':
shape = Shape('rectangle', 'big')
print('{} has {} edges'.format(shape.name, shape.number_of_edges))
print()
shape = Triangle('rectangle', 'junk')
print('{} has {} edges'.format(shape.name, shape.number_of_edges))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment