Last active
September 11, 2017 21:45
-
-
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/
This file contains 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
""" | |
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