Skip to content

Instantly share code, notes, and snippets.

@bradmontgomery
Last active September 11, 2017 21:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bradmontgomery/6432860 to your computer and use it in GitHub Desktop.
Save bradmontgomery/6432860 to your computer and use it in GitHub Desktop.
An example of python attributes, properties, and descriptors. This is the full code from this blog post: https://bradmontgomery.net/blog/2013/09/12/attribute-any-other-name/
"""
An example of python's attributes, properties, __getattr__, and Descriptors.
See the ``N`` class below.
For a full description, see this blog post:
https://bradmontgomery.net/blog/2013/09/12/attribute-any-other-name/
"""
def is_prime(number):
"""Determine if a number is prime. Shamelessly taken from:
http://stackoverflow.com/a/4117879/182778
Returns True or False
"""
return number > 1 and all(number % i for i in xrange(2, number))
class PrimeNumbers(object):
"""This class implements a descriptor (ie. a property or attribute) that
will only store Prime Numbers. The class on which it is attached must have
a ``numbers`` attribute."""
def filter_primes(self, numbers):
"""Use the ``is_prime`` function to pluck only primes from a list of
numbers."""
return filter(is_prime, numbers)
def __get__(self, instance, owner):
"""Get only the prime numbers from the ``numbers`` attribute on the
``instance`` object (an N object).
Note:
* ``instance`` will be an instance of our N class.
* ``owner`` will be a reference to the N class (not an instance
of it)
"""
return self.filter_primes(instance.numbers)
def __set__(self, instance, values):
"""Set the value of ``instance.numbers``, but *only* store primes.
``values`` is just a list of numbers.
"""
instance.numbers = self.filter_primes(values)
class N(object):
"""A simple class illustrating ways to access an "attribute"."""
numbers = range(10)
prime_numbers = PrimeNumbers()
@property
def even_numbers(self):
return [num for num in self.numbers if num % 2 == 0]
@even_numbers.setter
def even_numbers(self, values):
# Just pass any values on to the ``numbers`` attribute
self.numbers = values
def __getattr__(self, name):
if name == "odd_numbers":
return [num for num in self.numbers if num % 2 != 0]
# Raise an AttributeError, for all other attribute names.
raise AttributeError("'N' object has no attribute '{0}'".format(name))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment