Giving structure (and documentation!) to the properties you use in your classes avoids confusion and allows users to interact flexibly and provide multiple styles of input, have those inputs validated, and allow you as a developer to set expectations for what you want to work with.
properties package allows you to create strongly typed objects in a
consistent way. This allows you to hook into notifications and other libraries.
API Documentation is available at ReadTheDocs.
To install the repository, ensure that you have pip installed and run:
pip install properties
For the development version:
git clone https://github.com/3ptscience/properties.git cd properties pip install -e .
Lets start by making a class to organize your coffee habits.
import properties class CoffeeProfile(properties.HasProperties): name = properties.String('What should I call you?') count = properties.Integer( 'How many coffees have you had today?', default=0 ) had_enough_coffee = properties.Bool( 'Have you had enough coffee today?', default=False ) caffeine_choice = properties.StringChoice( 'How do you take your caffeine?' , choices=['coffee', 'tea', 'latte', 'cappuccino', 'something fancy'], required=False )
CoffeeProfile class has 4 properties, all of which are documented!
These can be set on class instantiation:
profile = CoffeeProfile(name='Bob') print(profile.name) Out : Bob
Since a default value was provided for
had_enough_coffee, the response is (naturally)
print(profile.had_enough_coffee) Out : False
We can set Bob’s
caffeine_choice to one of the available choices; he likes coffee
profile.caffeine_choice = 'coffee'
Also, Bob is half way through his fourth cup of coffee today:
profile.count = 3.5 Out : ValueError: The 'count' property of a CoffeeProfile instance must be an integer.
Ok, Bob, chug that coffee:
profile.count = 4
Now that Bob’s
CoffeeProfile is established,
check that it is valid:
profile.validate() Out : True
Property Classes are auto-documented in Sphinx-style reStructuredText!
When you ask for the doc string of
CoffeeProfile, you get
**Required Properties:** * **count** (:class:`Integer <properties.basic.Integer>`): How many coffees have you had today?, an integer, Default: 0 * **had_enough_coffee** (:class:`Bool <properties.basic.Bool>`): Have you had enough coffee today?, a boolean, Default: False * **name** (:class:`String <properties.basic.String>`): What should I call you?, a unicode string **Optional Properties:** * **caffeine_choice** (:class:`StringChoice <properties.basic.StringChoice>`): How do you take your caffeine?, any of "coffee", "tea", "latte", "cappuccino", "something fancy"