Last active
April 19, 2017 16:25
-
-
Save zengyu714/b146aae493f0c52d40771ea50038748f to your computer and use it in GitHub Desktop.
Python gist
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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) | |
| # ---------------------------------------------------------------------------- |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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