Skip to content

Instantly share code, notes, and snippets.

@zengyu714
Last active April 19, 2017 16:25
Show Gist options
  • Select an option

  • Save zengyu714/b146aae493f0c52d40771ea50038748f to your computer and use it in GitHub Desktop.

Select an option

Save zengyu714/b146aae493f0c52d40771ea50038748f to your computer and use it in GitHub Desktop.
Python gist
class Structure:
# Class variable that specifies expected fields.
_fields= []
def __init__(self, *args):
if len(args) != len(self._fields):
raise TypeError('Expected {} arguments'.format(len(self._fields)))
# Set the arguments.
for name, value in zip(self._fields, args):
setattr(self, name, value)
# Class definitions
# ----------------------------------------------------------------------------
# class Point(Structure):
# _fields = ['x', 'y']
#
# class Circle(Structure):
# _fields = ['radius']
#
# def area(self):
# return math.pi * self.radius ** 2
# ----------------------------------------------------------------------------
# Usage
# ----------------------------------------------------------------------------
# p = Point(1, 2)
# c = Circle(3)
# ----------------------------------------------------------------------------
# Solution 1
# Map the keyword arguments corresponding to the attribute names specified in `_fields`.
# --------------------------------------------------------------------------------------
class Structure:
_fields= []
def __init__(self, *args, **kwargs):
if len(args) > len(self._fields):
raise TypeError('Expected {} arguments'.format(len(self._fields)))
# Set all of the positional arguments.
for name, value in zip(self._fields, args):
setattr(self, name, value)
# Set the remaining keyword arguments.
for name in self._fields[len(args):]:
setattr(self, name, kwargs.pop(name))
# Check for any remaining unknown arguments
if kwargs:
raise TypeError('Invalid argument(s): {}'.format(','.join(kwargs)))
# Usage
# -----------------------------------------------------------------------------
# class ABC(Structure):
# _fields = ['A', 'B', 'C']
#
# s1 = ABC('a', 'b', 'c')
# s2 = ABC('a', 'b', C='c')
# s3 = ABC('a', B='b', C='c')
# -----------------------------------------------------------------------------
# Solution 2
# Use keyword arguments as additional attributes to the structure not specified in `_fields`.
# -------------------------------------------------------------------------------------------
class Structure:
_fields= []
def __init__(self, *args, **kwargs):
if len(args) != len(self._fields):
raise TypeError('Expected {} arguments'.format(len(self._fields)))
# Set the arguments.
for name, value in zip(self._fields, args):
setattr(self, name, value)
# Set the additional arguments (if any).
extra_args = kwargs.keys() - self._fields
for name in extra_args:
setattr(self, name, kwargs.pop(name))
if kwargs:
raise TypeError('Duplicate values for {}'.format(','.join(kwargs)))
# Usage
# -----------------------------------------------------------------------------
# class Stock(Structure):
# _fields = ['name', 'shares', 'price']
#
# s1 = Stock('ACME', 50, 91.1)
# s2 = Stock('ACME', 50, 91.1, date='8/2/2012')
# -----------------------------------------------------------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment