attributes | Module to facilitate attribute definition. |
InitializationError | Initialization failed or incomplete. |
NameClashWarning | Name clash. |
NameClashWarning1 | Name clash. |
NameClashWarning2 | Name clash. |
Archivable | Convenience class implementing |
StateVars(*varargin, **kwargs) | Base class for objects that support definition of attributes through the specification of _state_vars class attributes and then processed by process_vars(). |
Container(*varargin, **kwargs) | Simple container class. |
Attr | Base class for all attribute types. |
Excluded(value) | Excluded variable. |
Internal(value) | Internal variable. |
Fast(value) | Fast variable. |
Computed(*v, **kw) | Computed attributes. |
ClassVar(value) | Class variables (not associated with instances). |
NoCopy(value[, copy]) | Default value for objects that should not be copied (or copied with a custom copier copy). |
Delegate(cls[, vars, methods, value, cached]) | Delegate Class. |
Ref(ref[, cached, method]) | Ref Class. Represents an attribute reference to another |
attribute | Attribute class: like property, but with default operators. |
parameter | Parameter class: Turns a function into a parameter. |
calculate | Decorator for calculational functions that should be memoized. |
MemoizedContainer(*argv, **kwargs) | The paradigm for this class is that one has a set of parameters (call them x[0], x[1] etc.) and a set of functions that depend on these parameters (call them f[0], f[1] etc.). |
option | >>> class A(object):
|
Options([c]) | Options class. |
RecView | A simple subclass of the numpy recarray record array class that provides automatic conversion to a recarray. |
Calculator(*argv, **kwargs) | This class represents some data and values that must be calculated by a function calculate. |
process_vars(*args, **kw) | Return (results, wrap__init__). |
class_NamedArray(array_[, names]) | Return a class that is a subclass of array_.__class__ but that allows the elements to be accessed through a named member syntax. |
recview(a, names[, formats, dtype]) | Return a view of a as a recarray with defined field names. |
Inheritance diagram for mmf.objects:
This file contains a set of classes and meta-classes that allow objects to inherit useful functionality dealing with attributes, automatic calculations etc.
The highlight of this module is StateVars. The provides a powerful method for providing and documenting attributes with mechanisms for specifying defaults and delegates.
Attention has been given to making getting attributes as efficient as if they were standard attributes. Setting attributes is not so efficient, however, as many checks are done at this stage. This reflects the common usage of attributes such as parameters that are set only once in a while but accessed frequently.
Note
Getting attributes is somewhat inefficient for references as lookup must generally be performed. This penalty can be overcome by allowing references to cache values in the local dictionary, but this can get out of sync if the referenced values are in a delegate and changed via the delegate.
In the StateVars and its descendants, the role of StateVars.__init__() and the inherited __init__() method changes slightly from the usual role as an initializer. The semantics are that of an initializer that ensures the class is in a consistent state after initialization and after variable changes. The following changes have been made:
StateVars.__setattr__() calls __init__() whenever a variable is assigned. The name of the change variable is passed as a keyword argument so that a clever __init__() can avoid performing unnecessary computations. (See also StateVars.suspend(), StateVars.resume(), and StateVars.initialize()).
Warning
During construction, all default values are also assigned, and these assignments are included as keyword arguments to __init__(). Thus, there is no way of knowing exactly what arguments were specified by the user. This is intentional so that code to compute Computed variables can simply check for all values that have been set – default or otherwise – and compute what is needed.
The workaround is to set a special default value (such as None or defining a special object containing the value) so that you can differentiate from a significant value. Of course, if the user provides exactly this value, you are in the same boat. (Consider using a private class for example to prevent this.)
StateVars.__new__() also wraps the StateVars.__init__() method defined by the class to provide the following behaviour. (This is defined in _get_processed_vars().)
Thus, the main purpose of __init__() is to compute all Computed variables from the changed (or initialized) values of the other class parameters. Here is a skeleton:
def __init__(self, *varargin, **kwargs):
if (1 == len(varargin) and not kwargs):
# Called as a copy constructor. State has been copied from
# other by __new__. You do not need to copy the
# attributes here, but may need to copy calculated
# parameters that are cached. If kwargs is not empty,
# then additional values have been specified and need to
# be processed, so we exclude that case here
_other = varargin[0]
elif 1 < len(varargin):
# Another argument passed without kw. Error here.
raise ValueError("StateVars accepts only keyword arguments.")
else:
# Process the changed variables as specified in kwargs
# Call the base __init__ methods unless you explicitly set
# _call_base__init__ is set
<BaseClass>.__init__(self, *varagin, **kwargs)
# For all computed vars, if a dependent variable is in
# kwargs, then recompute it.
Properties can have three roles:
The first two roles will be deduced automatically if a property exists but is not in _state_vars. The last role requires both the existence of the property and an entry in _state_vars.
Copying in python can be a slippery business, especially if one wants to maintain some shared data, or to use functions, method, or classes as data. First we define
Todo
Revisit copying, especially deepcopy to remove the need for hacks.
In order to manage the copying and referencing of data we use the following semantics:
Todo
Add support for nicely printing: i.e. flags or something to indicate how the object should print.
Todo
Add Dependent like Required so that some values can be used, represented, etc. but are the result of calculations. Errors or warnings should be issued if the user tries to set these.
Todo
Complete _preprocess() to support optional syntax.
Todo
Provide more functionality for subclasses to change default values of the parent classes. For example, if a parent class delegates x=a.x, then the subclass has to include (‘a.x’, 5) in _state_vars to change the default. If, instead, the subclass includes (‘x’, 5), then this will create a new variable and the delegation will be broken. This should raise a warning. Perhaps add a new type Default so that one can do (‘x’, Default(5)). This will raise an error unless x is already a properly settable attribute in a parent, and will use the previous definition, including any delegation. A related issue that this would solve is that there is presently no way to provide defaults for non-stored attributes that provide both setters and getters.
Todo
Multiple inheritance requires a call to process_vars() even if no new _state_vars are added. There is probably no solution without __metaclass__ trickery.
Todo
If a class is defined in a local scope such as a function, then the local variables will be added to the class __dict__. This is because of how process_vars() works, but I don’t know how to fix it. See the test test_local_scope(). Somehow the dic passed to the metaclass includes local variables...
Todo
StateVars.__iter__() uses hasattr, which calls getattr. If the user defines getters, then this is can be problematic.
Here is another possible syntax (not yet fully implemented, see _preprocess()). The idea here is to define simple state vars of the class that are of a special type, either one of the Required, Delegate etc. etc., or a tuple of length 2 with the second element of a special type. Then delete these and add the corresponding entries to _state_vars. For example, the following could be equivalent:
class A(StateVars):
_state_vars = [
'a',
('b', 0),
('x', 1, 'variable x'),
('y=x', 'variable y (delegates to y)'),
('z', Required, 'a required var'),
('c', ClassVar(4), 'a class var')
]
process_vars()
class A(StateVars):
a = Attr
b = 0, Attr
x = 1, Attr('variable x')
y = 'x', Ref('variable y (delegates to y)')
z = Required('a required var'),
c = 4, ClassVar('a class var')
process_vars()
Note
To do this, we should change the syntax of the various classes so that they can accept documentation as their first argument (this will be removed by _preprocess() and placed as the third element in the _state_vars tuple, but we need to allow for this here).
Bases: exceptions.Exception
Initialization failed or incomplete.
x.__init__(...) initializes x; see help(type(x)) for signature
Bases: exceptions.UserWarning
Name clash. Name already defined.
The default is to ignore warnings of type NameClassWarning1 but show those of type NameClassWarning2 which tend to be more severe. If you want to ignore all such errors (after debugging!) so you can disable this using simplefilter(). See warnings for possible actions: the most common are ‘one’ or ‘ignore’.
You can also do this on a class by class basis by defining the class attribute _ignore_name_clash. This should be a set of the known name clashes.
Note
This may be emitted because of spurious variables added to the class __dict__ if the class was defined within a local scope.
x.__init__(...) initializes x; see help(type(x)) for signature
Filter NameClashWarnings with specified action.
Bases: mmf.objects.NameClashWarning
Name clash. Name already defined.
This is a less serious warning, for example, it is raised when default values are changed. It is by default disabled.
x.__init__(...) initializes x; see help(type(x)) for signature
Bases: mmf.objects.NameClashWarning
Name clash. Name already defined.
This is a more serious warning about name-clashes that are indicative of bugs. It is by default enabled to warn once.
x.__init__(...) initializes x; see help(type(x)) for signature
Bases: object
Convenience class implementing interfaces.IArchivable.
The user only needs to implement the function items().
Examples
>>> class A(Archivable):
... def __init__(self, a, b):
... self.data = [a, b]
... def items(self):
... return zip(('a', 'b'), self.data)
>>> a = A(1, 2)
>>> a
A(a=1, b=2)
Methods
archive(name) | Return a string representation that can be executed to restore the object. |
archive_1([env]) | Return (rep, args, imports). |
items() | Return a list [(name, obj)] of (name, object) pairs |
x.__init__(...) initializes x; see help(type(x)) for signature
Return a string representation that can be executed to restore the object.
Examples
(Note: We can’t actually do this because the class A cannot be imported from a module if it is defined at the interpreter):
class A(Archivable):
def __init__(self, a):
self.a = a
def items(self):
return [('a', self.a)]
a = A(6) # Create an instance
s = a.archive('n') # Get string archive
env = {} # Define an environment
exec(s, env) # Evaluate the string in env
o = env['n'] # Access the object from env
o.a
Return (rep, args, imports).
Defines a representation rep of the instance self where the instance can be reconstructed from the string rep evaluated in the context of dict args with the specified imports = list of (module, iname, uiname) where one has either “import module as uiname”, “from module import iname” or “from module import iname as uiname”.
Return a list [(name, obj)] of (name, object) pairs where the instance can be constructed as ClassName(name1=obj1, name2=obj2, ...).
The default implementation just uses the elements in self.__dict__.
Bases: mmf.objects.Archivable
Base class for objects that support definition of attributes through the specification of _state_vars class attributes and then processed by process_vars(). For example:
class Complex(StateVars):
"A complex number class."
_state_vars = [
('real', 0, 'Real part'),
('imag', 0, 'Imaginary Real part')]
process_vars()
...
When defining a StateVars class one should:
Define the _state_vars attribute as discussed below.
Call process_vars().
Define __init__() to specifying initialization. Be sure to call __init__() for any base classes (not needed if inheriting directly from StateVars. Remember that you do not need to assign any parameters in _state_vars — these will be assigned in the constructor __new__(). However, any Computed attributes will need to be computed here, and one might like to perform checks of the parameter values.
Remember that __init__() will be called whenever parameter change in a shallow way (i.e. through direct assignment).
See __init__() Semantics for details.
Profile performance: if performance is too slow then:
The call to process_vars() will parse _state_vars from the class definition and any superclasses. These are accumulated and described in the following class attributes:
Notes
The state variables with names begining with underscores ‘_...’ are always excluded unless explicitly included in _state_vars.
_state_vars may be a dictionary with default values, or simply a list/set of variable names. See below for examples.
We also allow for parameters to delegate to other parameters by attributes with the following forms:
These are the normalized forms. Shortcuts are:
Examples
>>> class A(StateVars):
... _state_vars = [('x', 10), ('y', 100)]
... process_vars()
>>> a = A(x=1.0)
>>> a
A(x=1.0)
>>> print a
x=1.0
y=100
>>> a.y = 5
>>> a
A(x=1.0, y=5)
Setting other attributes is not transparently supported...
>>> a.z = 6
Traceback (most recent call last):
...
AttributeError: Cannot set attribute 'z' of object 'A'
You can if you must, however...
>>> a.__dict__['z'] = 6
>>> a.z
6
But direct assignment is still not supported
>>> a.z = 7
Traceback (most recent call last):
...
AttributeError: Cannot set attribute 'z' of object 'A'
If you forget to call process_vars()...
>>> class B(A):
... _state_vars = [('LargeObject', Excluded)]
A helpful reminder is displayed upon use...
>>> b = B()
Traceback (most recent call last):
...
InitializationError: 'B' class unprocessed.
Please call process_vars() in class definition.
The idea of Excluded parameters is to store large temporary calculations for inspection. These should never be used within the class, and production code should function without these objects. They are intended for debugging, or for presenting users with intermediate results. Final results should be returned as different persistent structures.
>>> class B(A):
... _state_vars = [('LargeObject', Excluded)]
... process_vars()
>>> b = B(x=2)
>>> print b
x=2
y=100
>>> b.LargeObject = 'Elephant'
>>> b
B(x=2)
>>> print b
x=2
y=100
Excluded:
LargeObject=Elephant
The __init__() method should do any lengthy calculations.
>>> class C(StateVars):
... _state_vars = ['x', 'y',
... ('x2', Computed),
... ('y2', Computed),
... ('z', 0),
... ('t', 0),
... ('e', Excluded(0))]
... _nodeps = ['z']
... process_vars()
... def __init__(self, **kwargs):
... print "Initializing"
... if 'x' in kwargs:
... print "Calculating x^2"
... self.x2 = self.x**2
... if 'y' in kwargs:
... print "Calculating y^2"
... self.y2 = self.y**2
>>> c = C(x=1, y=2)
Initializing
Calculating x^2
Calculating y^2
>>> print c
x=1
y=2
z=0
t=0
Computed:
x2=1
y2=4
Excluded:
e=0
Note that __init__() is also responsible for recomputing values if the inputs change. If the calculations are tedious, then a controlled computation like that shown should be used to reduce the work.
Note
This recomputing only works for attributes that are assigned, i.e. iff __setattr__() is called. If an attribute is mutated, then __getattr__() is called and there is no (efficient) way to determine if it was mutated.
(Future versions might consider tagging all “accessed” attributes, however, in order to determine if a mutable object was changed, one would need to store a copy, which could provide a bad performance hit).
>>> c.x = 3
Initializing
Calculating x^2
>>> print c
x=3
y=2
z=0
t=0
Computed:
x2=9
y2=4
Excluded:
e=0
>>> c.t = 6
Initializing
>>> c.z = 7
>>> c.e = 9
Note that __init__() was not called when z was assigned because it is included in the _nodeps list or when e was assigned because it is Excluded. Calls to __init__() can be deferred by using suspend() and resume():
>>> c.suspend()
>>> c.x = 4
>>> c.y = 6
>>> c.resume()
Initializing
Calculating x^2
Calculating y^2
>>> print c
x=4
y=6
z=7
t=6
Computed:
x2=16
y2=36
Excluded:
e=9
Note, you may use properties. If these are not included in _state_vars, then these will be added to _state_vars by process_vars() either as un-stored Computed attributes or as _settable_properties. Neither will be archived or returned by items().
>>> class E1(StateVars):
... _state_vars = ['y']
... process_vars()
... @property
... def x(self):
... '''Another name for 2*y'''
... print "Getting x=2*y"
... return 2*self.y
>>> a = E1(y=2) # x is not set but getattr is called by hasattr...
Getting x=2*y
>>> a # x is not set but getattr is called by hasattr...
Getting x=2*y
E1(y=2)
>>> a.x = 6
Traceback (most recent call last):
...
AttributeError: Cannot set attribute 'x' of object 'E1'
Here is an example where the property is settable (but still will not be archived.)
>>> class E2(StateVars):
... _state_vars = ['y']
... process_vars()
... def set_x(self, x):
... '''Another name for `2*y`'''
... self.y = x/2
... print "Setting x=2*y"
... def get_x(self):
... print "Getting x=2*y"
... return 2*self.y
... x = property(get_x, set_x)
>>> a = E2(y=2)
>>> a
E2(y=2)
>>> a.x = 6
Setting x=2*y
>>> print a
y=3.0
If you want the property to represent stored data, you must explicitly include it in _state_vars and suppress the name clash warning:
>>> class F(StateVars):
... _ignore_name_clash = set(['x'])
... _state_vars = ['y', 'x']
... process_vars()
... def set_x(self, x):
... '''A stored property'''
... self.__dict__['x'] = x
... print "Setting x"
... def get_x(self):
... print "Getting x"
... return self.__dict__['x']
... x = property(get_x, set_x)
>>> a = F(y=2)
Getting x
>>> a # Even though x is not set, getattr is called by hasattr...
Getting x
F(y=2)
>>> a.x = 5
Setting x
>>> print a
Getting x
Getting x
y=2
x=5
If no setter is defined, the property will be included as a Computed value.
Note
Again, there are some extra Getting calls as hasattr() is called to check if the attribute exists.
>>> class F(StateVars):
... _ignore_name_clash = set(['y'])
... _state_vars = [
... ('y', 5, 'This property has a default and is stored')]
... process_vars()
... @property
... def x(self):
... '''property `x=2*y`'''
... print "Getting x"
... return self.y*2
... def set_y(self, y):
... self.__dict__['y'] = y
... print "Setting y"
... def get_y(self):
... print "Getting y"
... return self.__dict__['y']
... y = property(get_y, set_y)
>>> a = F() # x is not set but getattr is called by hasattr...
Getting y
Setting y
Getting y
Getting x
Getting y
>>> a
Getting y
Getting x
Getting y
Getting y
Getting y
Getting y
F()
>>> print a
Getting y
Getting y
Getting x
Getting y
Getting x
Getting y
y=5
Computed:
x=10
Class variables may also be specified. This provides a way of documenting and requiring class-specific variables. These variables are not archived or printed, but are documented in the class. They act as “class constants”.
>>> class F(StateVars):
... _state_vars = [('A', ClassVar(Required), "Required 'class' var"),
... ('B', ClassVar(1), "Optional class var"),
... ('a', 2, "Regular parameter")]
... process_vars()
>>> help(F)
Help on class F...
class F(StateVars)
| Usage: F(a=2)
|
| **Class Variables:**
| A: Required 'class' var
| B: Optional class var
|
| **State Variables:**
| a: Regular parameter
|
| Method resolution order:
...
| Data and other attributes defined here:
|
| A = Required
...
|
| B = 1
...
>>> print F.__doc__
Usage: F(a=2)
Attributes
----------
**Class Variables:**
A: Required 'class' var
B: Optional class var
**State Variables:**
a: Regular parameter
>>> f = F()
Traceback (most recent call last):
...
AttributeError: Required class variable 'A' not initialized in class 'F'
>>> class G(F):
... _ignore_name_clash = set(['A', 'B'])
... _state_vars = [('A', ClassVar(2), 'No longer required'),
... ('B', ClassVar(2))]
... process_vars()
>>> print G.__doc__
Usage: G(a=2)
Attributes
----------
**Class Variables:**
A: No longer required
B: Optional class var
**State Variables:**
a: Regular parameter
>>> g = G()
>>> g
G()
>>> print g
a=2
>>> g.A, g.B
(2, 2)
If a class variable is specified, it may later be replaced by an instance variable through inheritance. Again, be sure to ignore the name clash warning if this is deliberate.
>>> class H(F):
... _ignore_name_clash = set(['A'])
... _state_vars = [('A', Required)]
... process_vars()
>>> print H.__doc__
Usage: H(A=Required, a=2)
Attributes
----------
**Class Variables:**
B: Optional class var
**State Variables:**
A: Required 'class' var
a: Regular parameter
>>> H(a=2)
Traceback (most recent call last):
...
ValueError: Required attribute 'A' not defined.
You may delegate variables to a member variable. By default delegation will allow arguments for the delegate to be passed to the delegate from the main object. First we create two classes A and B that we will use as delegates, then a class C that delegates to these. For class A will delegate all attributes from the class directly using the Delegate specifier with the class as an argument. This will specify that the object should have an instance a constructed from parameters passed directly to C. These will all be mirrored with parameters in C that dispatch directly to the instance a.
>>> class A(StateVars):
... _state_vars = [('x', 1, 'var x')]
... process_vars()
>>> class B(StateVars):
... _state_vars = [('t', 1, 'var t'),
... ('z', 2, 'var z')]
... process_vars()
>>> class C(StateVars):
... _state_vars = [
... ('a', Delegate(A)), # This will be constructed by __new__
... ('b', B()), # Previously constructed object
... ('y=a.x', 10), # Ref called y to a.x with new default
... ('b.z', 3)] # Change of value upon construction.
... process_vars()
>>> c = C()
>>> c.a
A(x=10)
>>> c.b
B(z=3)
An example of delegating a required variable:
>>> class A(StateVars):
... _state_vars = [('x=b.x', Required),
... ('b', Container())]
... process_vars()
>>> a = A(x=[]); a
A(b=Container(x=[]))
>>> a.x.append(3); a
A(b=Container(x=[3]))
Note how reassignment works:
>>> A(x=[4], b=Container(x=[3]))
A(b=Container(x=[4]))
Note
This is not a good idea! Please ignore... It is possible, but fraught with danger (it will break repr for example!)
This is best resolved by either making the references Computed attributes (read-only) or excluding the referenced object and making it private.
>>> class A(StateVars):
... _state_vars = [('x=_b.x', Required),
... ('_b', Excluded(Container()))]
... process_vars()
>>> A(x=[])
A(x=[])
Todo
Think about this. This is not a good solution! Perhaps one should allow delegate objects that are hidden so that the class controls them properly with construction etc.
Delegation also ensures that a new copy of the object will be initialized upon copy construction rather than just linked.
>>> class A(StateVars):
... pass
>>> class B(StateVars):
... _state_vars = [('a', Delegate(A))]
... process_vars()
>>> b1 = B()
>>> b2 = B(b1)
>>> id(b1.a) == id(b2.a)
False
In order to avoid copy construction from copying objects, they should have the value NotImplemented:
>>> class A(StateVars):
... _state_vars = [('c', 1)]
... process_vars()
>>> a = A()
>>> a.c = None
>>> b = A(a)
>>> print b.c
None
>>> a.c = NotImplemented
>>> b = A(a)
>>> b.c
1
Note that the value here is the default: the NotImplemented value of a.c is ignored.
When inheriting from classes that define __init__(), one must make sure that the base class versions are called, either by setting _call_base__init__ or explicitly. (Note that StateVars only has a dummy __init__() method, so if you only inherit from this class, or from descendants that do not redefine __init__(), then you may omit this call, but it is considered bad form.)
>>> class A(StateVars):
... _state_vars = [
... ('a', Required),
... ('c_a', Computed)]
... process_vars()
... def __init__(self, *v, **kw):
... print('Computing c_a...')
... self.c_a = self.a*2
>>> class B_bad(A):
... _state_vars = [
... ('c_b', Computed)]
... process_vars()
... def __init__(self, *v, **kw):
... print('Computing c_b...')
... self.c_b = self.a*3
>>> a = A(a=1)
Computing c_a...
>>> b = B_bad(a=1) # This fails to call base constructor
Computing c_b...
>>> b.c_a
Traceback (most recent call last):
...
AttributeError: 'B_bad' object has no attribute 'c_a'
Here are two correct ways:
>>> class B1(A):
... _state_vars = [
... ('c_b', Computed)]
... process_vars()
... def __init__(self, *v, **kw):
... A.__init__(self, *v, **kw)
... print('Computing c_b...')
... self.c_b = self.a*3
>>> class B2(A):
... _state_vars = [
... ('c_b', Computed)]
... _call_base__init__ = True
... process_vars()
... def __init__(self, *v, **kw):
... print('Computing c_b...')
... self.c_b = self.a*3
>>> b = B1(a=1)
Computing c_a...
Computing c_b...
>>> b.c_a, b.c_b
(2, 3)
>>> b = B2(a=1)
Computing c_a...
Computing c_b...
>>> b.c_a, b.c_b
(2, 3)
StateVar object know how to be archived. One can modify this by defining two hooks: _pre_hook_archive() and _post_hook_archive(). These will be called before and after the call to items() that is used to archive the object. One common use of these is to convert a large list (useful for concatenation) to a single array to be stored using HD5 for example.
>>> import numpy as np
>>> class A(StateVars):
... _state_vars = [('x', [])]
... process_vars()
... def __init__(self, *v, **kw):
... if 'x' in kw and isinstance(self.x, np.ndarray):
... self.x = [_a for _a in self.x]
... def _pre_hook_archive(self):
... self.__dict__['x'] = np.asarray(self.x)
... def _post_hook_archive(self):
... self.__init__(x=self.x)
>>> a = A(x=[np.ones((2,1)) for _n in xrange(5)])
>>> a.x
[array([[ 1.],
[ 1.]]), array([[ 1.],
[ 1.]]), array([[ 1.],
[ 1.]]), array([[ 1.],
[ 1.]]), array([[ 1.],
[ 1.]])]
>>> a._pre_hook_archive()
>>> a.x
array([[[ 1.],
[ 1.]],
[[ 1.],
[ 1.]],
[[ 1.],
[ 1.]],
[[ 1.],
[ 1.]],
[[ 1.],
[ 1.]]])
>>> a._post_hook_archive()
>>> a.x
[array([[ 1.],
[ 1.]]), array([[ 1.],
[ 1.]]), array([[ 1.],
[ 1.]]), array([[ 1.],
[ 1.]]), array([[ 1.],
[ 1.]])]
Attributes
_state_vars | list() -> new empty list |
_nodeps | set() -> new empty set object |
_vars | list() -> new empty list |
_defaults | |
_class_vars | set() -> new empty set object |
_computed_vars | |
_excluded_vars | set() -> new empty set object |
_method_vars | set() -> new empty set object |
_dynamic | bool(x) -> bool |
_refs | |
_irefs | |
_delegates | |
_settable_properties | set() -> new empty set object |
_call_base__init__ | bool(x) -> bool |
_original__init__ | meth | This is the original __init__() function is stored here. After the class is finished, the original __init__() is replaced by a wrapper (defined in _get_processed_vars()) that sets the variables and then calls this (as well as the base constructors if _call_base__init__ is True.) |
Methods
all_items() | Return a list [(name, obj)] of (name, object) pairs containing all items available. |
archive(name) | Return a string representation that can be executed to restore the object. |
archive_1([env]) | Return (rep, args, imports). |
initialize(**kwargs) | Calls __init__() passing all assigned attributes. |
items([archive]) | Return a list [(name, obj)] of (name, object) pairs where the |
resume() | Resume calls to __init__() from __setattr__(), |
suspend() | Suspend calls to __init__() from |
This is the initialization routine. It is called after the attributes specified in _state_vars have been assigned.
The user version should perform any after-assignment initializations that need to be performed.
Note
Since all of the initial arguments are listed in kwargs, this can be used as a list of attributes that have “changed” allowing the initialization to be streamlined. The default __setattr__() method will call __init__() with the changed attribute to allow for recalculation.
This recomputing only works for attributes that are assigned, i.e. iff __setattr__() is called. If an attribute is mutated, then __getattr__() is called and there is no (efficient) way to determine if it was mutated.
Computed values with True Computed.save will be passed in through kwargs when objects are restored from an archive. These parameters in general need not be recomputed, but this opens the possibility for an inconsistent state upon construction if a user inadvertently provides these parameters. Note that the parameters still cannot be set directly.
See __init__() Semantics for details.
Methods
all_items() | Return a list [(name, obj)] of (name, object) pairs containing all items available. |
archive(name) | Return a string representation that can be executed to restore the object. |
archive_1([env]) | Return (rep, args, imports). |
initialize(**kwargs) | Calls __init__() passing all assigned attributes. |
items([archive]) | Return a list [(name, obj)] of (name, object) pairs where the |
resume() | Resume calls to __init__() from __setattr__(), |
suspend() | Suspend calls to __init__() from |
This is the initialization routine. It is called after the attributes specified in _state_vars have been assigned.
The user version should perform any after-assignment initializations that need to be performed.
Note
Since all of the initial arguments are listed in kwargs, this can be used as a list of attributes that have “changed” allowing the initialization to be streamlined. The default __setattr__() method will call __init__() with the changed attribute to allow for recalculation.
This recomputing only works for attributes that are assigned, i.e. iff __setattr__() is called. If an attribute is mutated, then __getattr__() is called and there is no (efficient) way to determine if it was mutated.
Computed values with True Computed.save will be passed in through kwargs when objects are restored from an archive. These parameters in general need not be recomputed, but this opens the possibility for an inconsistent state upon construction if a user inadvertently provides these parameters. Note that the parameters still cannot be set directly.
See __init__() Semantics for details.
Return a list [(name, obj)] of (name, object) pairs containing all items available. This will include computed vars, reference, etc. and will likely be redundant.
See also
Return (rep, args, imports).
Same as Archivable.archive_1() except passes archive=True to items().
Return the keys accepted by the constructor.
>>> StateVars.class_keys()
[]
>>> class A(StateVars):
... _state_vars = ['a', 'b']
... process_vars()
>>> A.class_keys()
['a', 'b']
Return the dictionary that is a subset of kwargs containing the valid keyword arguments for the current object.
>>> class A(StateVars):
... _state_vars = ['a', 'b']
... process_vars()
>>> class B(StateVars):
... _state_vars = ['c', 'd']
... process_vars()
>>> def f(**kwargs):
... a = A(A.get_args(kwargs))
... b = B(B.get_args(kwargs))
... return a, b
>>> a, b = f(a=1, b=2, c=3, d=4)
>>> a, b
(A(a=1, b=2), B(c=3, d=4))
>>> Container(Container.get_args(a=1, b=2))
Container(a=1, b=2)
Get the names and default values of the constructor.
A tuple of four things is returned: (args, varargs, varkw, defaults). ‘args’ is a list of the argument names (it may contain nested lists). ‘varargs’ and ‘varkw’ are the names of the * and ** arguments or None. ‘defaults’ is an n-tuple of the default values of the last n arguments.
>>> StateVars.getargspec()
([], None, None, ())
>>> Container.getargspec()
([], None, 'kwargs', ())
>>> class D(StateVars):
... _state_vars = [('a', 0), ('b', Required), ('c', NotImplemented)]
... process_vars()
>>> D.getargspec()
(['b', 'a', 'c'], None, None, (0, NotImplemented))
Calls __init__() passing all assigned attributes. This should not typically be needed as the use of suspend and resume should function appropriately. This can be used to set a bunch of parameters, however.
Parameters : | <name> : value
|
---|
Examples
>>> class A(StateVars):
... _state_vars = ['a', ('x', Computed)]
... process_vars()
... def __init__(self, a=None):
... if a is None:
... print "Initializing: a not changed."
... else:
... print "Initializing: a changed."
... self.x = 2*a
>>> a = A(a=1); a.x
Initializing: a changed.
2
>>> a.a = 2; a.x
Initializing: a changed.
4
>>> a.suspend()
>>> a.a = 3
>>> a.resume(); a.x
Initializing: a changed.
6
>>> a.initialize();
Initializing: a not changed.
>>> a.initialize(a=8); a.x
Initializing: a changed.
16
Return a list [(name, obj)] of (name, object) pairs where the instance can be constructed as ClassName(name1=obj1, name2=obj2, ...).
Parameters : | archive : False, True, optional
|
---|
Resume calls to __init__() from __setattr__(), first calling __init__() with all the cached changes.
Suspend calls to __init__() from __setattr__(), but keep track of the changes.
Bases: mmf.objects.StateVars
Simple container class. This is just a StateVars class with allowed dynamic allocation and with __getitem__() and __setitem__() mapped to __getattr__() and __setattr__() so that it behaves like a dictionary.
Examples
>>> a = Container(a=1, b=2)
>>> print a
a=1
b=2
>>> a.z = 4 # Can define new attributes
>>> a.z
4
>>> a['b'] = 3 # Can use dictionary syntax
>>> print a
a=1
b=3
z=4
We also include an update method that updates the dictionary
>>> a.update(Container(b=3, c=4))
>>> print a
a=1
c=4
b=3
z=4
If you specify _dynamic in the constructor, then the Container will no longer accept new variable definitions:
>>> c = Container(a=1, b=2, _dynamic=False)
>>> print c
a=1
b=2
>>> c.z = 4
Traceback (most recent call last):
...
AttributeError: Cannot set attribute 'z' of object 'Container'
Methods
all_items() | Return a list [(name, obj)] of (name, object) pairs containing all items available. |
archive(name) | Return a string representation that can be executed to restore the object. |
archive_1([env]) | Return (rep, args, imports). |
initialize(**kwargs) | Calls __init__() passing all assigned attributes. |
items([archive]) | Return a list [(name, obj)] of (name, object) pairs where the |
resume() | Resume calls to __init__() from __setattr__(), |
suspend() | Suspend calls to __init__() from |
update(container) | Update the items from container. |
This is the initialization routine. It is called after the attributes specified in _state_vars have been assigned.
The user version should perform any after-assignment initializations that need to be performed.
Note
Since all of the initial arguments are listed in kwargs, this can be used as a list of attributes that have “changed” allowing the initialization to be streamlined. The default __setattr__() method will call __init__() with the changed attribute to allow for recalculation.
This recomputing only works for attributes that are assigned, i.e. iff __setattr__() is called. If an attribute is mutated, then __getattr__() is called and there is no (efficient) way to determine if it was mutated.
Computed values with True Computed.save will be passed in through kwargs when objects are restored from an archive. These parameters in general need not be recomputed, but this opens the possibility for an inconsistent state upon construction if a user inadvertently provides these parameters. Note that the parameters still cannot be set directly.
See __init__() Semantics for details.
Methods
all_items() | Return a list [(name, obj)] of (name, object) pairs containing all items available. |
archive(name) | Return a string representation that can be executed to restore the object. |
archive_1([env]) | Return (rep, args, imports). |
initialize(**kwargs) | Calls __init__() passing all assigned attributes. |
items([archive]) | Return a list [(name, obj)] of (name, object) pairs where the |
resume() | Resume calls to __init__() from __setattr__(), |
suspend() | Suspend calls to __init__() from |
update(container) | Update the items from container. |
This is the initialization routine. It is called after the attributes specified in _state_vars have been assigned.
The user version should perform any after-assignment initializations that need to be performed.
Note
Since all of the initial arguments are listed in kwargs, this can be used as a list of attributes that have “changed” allowing the initialization to be streamlined. The default __setattr__() method will call __init__() with the changed attribute to allow for recalculation.
This recomputing only works for attributes that are assigned, i.e. iff __setattr__() is called. If an attribute is mutated, then __getattr__() is called and there is no (efficient) way to determine if it was mutated.
Computed values with True Computed.save will be passed in through kwargs when objects are restored from an archive. These parameters in general need not be recomputed, but this opens the possibility for an inconsistent state upon construction if a user inadvertently provides these parameters. Note that the parameters still cannot be set directly.
See __init__() Semantics for details.
Update the items from container.
Bases: mmf.objects.Archivable
Base class for all attribute types.
Methods
archive(name) | Return a string representation that can be executed to restore the object. |
archive_1([env]) | Return (rep, args, imports). |
items() | Return all items to make object archivable. |
x.__init__(...) initializes x; see help(type(x)) for signature
Return all items to make object archivable. The attribute names are determined by inspecting the arguments to the constructor __init__().
Bases: mmf.objects._objects.HasDefault
Excluded variable.
These are not archived and are intended for either flags to indicate that a particular method is executing, or for non-essential reporting of internal state/temporary data.
Methods
archive(name) | Return a string representation that can be executed to restore the object. |
archive_1([env]) | Return (rep, args, imports). |
items() | Return all items to make object archivable. |
Bases: mmf.objects.Excluded
Internal variable.
These are not archived and are intended for internal use only. Functionally equivalent to Excluded attributes and are presently implemented as these (and reported as these).
Methods
archive(name) | Return a string representation that can be executed to restore the object. |
archive_1([env]) | Return (rep, args, imports). |
items() | Return all items to make object archivable. |
Bases: mmf.objects._objects.HasDefault
Fast variable.
Like Excluded and Internal variables, these do not trigger a call to __init__() when they are set, but they are stored in the archive. They should be used for simple attributes like flags or counters. Make sure that nothing depends on the value though, otherwise the object might not be properly updated.
Methods
archive(name) | Return a string representation that can be executed to restore the object. |
archive_1([env]) | Return (rep, args, imports). |
items() | Return all items to make object archivable. |
Bases: mmf.objects.Attr
Computed attributes.
These are not assignable, and should be computed in __init__() from other parameters.
Parameters : | save : False, True, optional
|
---|
Examples
>>> Computed.save
False
>>> Computed(save=True)
Computed(save=True)
>>> Computed(2)
Traceback (most recent call last):
...
TypeError: Computed() has no default value. Did you mean ClassVar(2)?
Methods
archive(name) | Return a string representation that can be executed to restore the object. |
archive_1([env]) | Return (rep, args, imports). |
items() | Our constructor breaks the auto finding of attributes |
Our constructor breaks the auto finding of attributes
Bases: mmf.objects._objects.HasDefault
Class variables (not associated with instances).
Consequential class variables should always be defined (and/or redefined) through the _state_vars mechanism. Inconsequential class variables can bed defined normally but these will always be overridden by those defined through the _state_vars mechanism once process_vars() is called.
Methods
archive(name) | Return a string representation that can be executed to restore the object. |
archive_1([env]) | Return (rep, args, imports). |
items() | Return all items to make object archivable. |
Bases: object
Default value for objects that should not be copied (or copied with a custom copier copy). The default semantics are that initialization variables are copied with the copier supplied to process_vars() (deepcopy if not specified).
Examples
>>> import copy
>>> n = NoCopy(3); n
NoCopy(3)
>>> n.copy
<function <lambda> at ...>
>>> n = NoCopy(3, copy='copy'); n
NoCopy(3, copy='copy')
>>> n.copy is copy.copy
True
>>> n = NoCopy(3, copy='deepcopy'); n
NoCopy(3, copy='deepcopy')
>>> n.copy is copy.deepcopy
True
>>> n = NoCopy(3, copy=lambda x:x); n
NoCopy(3, copy=<function <lambda> at ...>)
>>> n.copy
<function <lambda> at ...>
Return the copier
Bases: mmf.objects._objects.HasDefault
Delegate Class.
An attribute with default value Delegate(A) will be initialized as A(**kw) where the attributes in A._state_vars are used as keyword arguments. Delegate(A, [‘x’,’y’]) is the same except only the specified attributes will be used. Note that the delegate constructor must accept these attributes as keyword args.
Member functions of the delegate may also be delegated, so that Delegate(A, [‘x’,’y’], methods=[‘f’]) will make the method f available in the top-level class.
A default may also be specified, in which case this will be used to initialize the object using the standard copy semantics as specified by NoCopy.
Examples
This is the simplest delegation to A. All variables in A._state_vars become members of D1:
>>> class A(StateVars):
... _state_vars = [('a', 1), ('b', 2)]
... process_vars()
>>> class D1(StateVars):
... _state_vars = [
... ('A_', Delegate(A), 'Delegate all vars')
... ]
... process_vars()
>>> d1 = D1(a=3); print d1
a=3
b=2
A_=a=3
b=2
The attributes a and b are actually the attributes of A_:
>>> d1
D1(A_=A(a=3))
>>> d1.a=5; print d1
a=5
b=2
A_=a=5
b=2
Now we delegate to B but include an explicit list of delegates. This is the safer thing to do as it reduces the chances of name clashes:
>>> class B(StateVars):
... _state_vars = [('c', 3), ('d', 4)]
... process_vars()
... def f(self):
... return self.c + self.d
>>> class D2(StateVars):
... _state_vars = [('B_', Delegate(B, ['c'], methods=['f']))]
... process_vars()
>>> d2 = D2(c=7); print d2
c=7
B_=c=7
d=4
Note that we can also call f: >>> d2.f() 11
If you want to delegate to an object that does not use _state_vars, you must explicitly specify these. Note that the ones you specify in the delegate must be accepted by the constructor.
>>> class C(Archivable):
... def __init__(self, x=1, y=2):
... self.x = x
... self.y = y
>>> class D3(StateVars):
... _state_vars = [('C_', Delegate(C, ['x','y']))]
... process_vars()
>>> d3 = D3(x=10); d3
D3(C_=C(y=2, x=10))
Note that the assignments are made after the attribute C_ is defined, so that the local kwargs overwrite the values passed in to C_:
>>> D3(x=12, y=2, C_=C(y=2, x=10))
D3(C_=C(y=2, x=12))
Notice that the delegation mechanism creates a new instance of C here, hence it is shown in the representation. (It is slightly redundant to have kwargs as well but this to show that they are indeed attributes.)
You can also specify a default in the class definition. You may also use NoCopy etc.
>>> c = C(x=-1,y=-2)
>>> class D4(StateVars):
... _state_vars = [('C_', Delegate(C, ['x','y'],
... value=NoCopy(c)))]
... process_vars()
This is dangerous though, because you will modify the original (and then since the default has changed, the changes will not appear in the representation!) >>> d4 = D4(x=5); d4 D4() >>> c C(y=-2, x=5) >>> id(c) == id(d4.C_) True
Finally, in order to optimize attribute access, you can specify that the delegate should be cached. This means that the delegated attributes will be cached in the instance __dict__ for efficient retrieval.
Warning
This can break code because it means that if you change an attribute in the delegate directly, the cache will not be updated until initialize() is called or the corresponding attribute is set via the reference.
>>> Delegate(None, ['x', 'y'])
Delegate(vars=['x', 'y'], cls=None)
>>> Delegate(None)
Delegate(cls=None)
>>> Delegate(None, vars=['x'], value=4)
Delegate(value=4, vars=['x'], cls=None)
Methods
archive(name) | Return a string representation that can be executed to restore the object. |
archive_1([env]) | Return (rep, args, imports). |
items() | Return all items to make object archivable. |
Bases: mmf.objects.Attr
Ref Class. Represents an attribute reference to another attribute.
Examples
>>> Ref('x')
Ref(ref='x')
>>> Ref('x', cached=True)
Ref(cached=True, ref='x')
Methods
archive(name) | Return a string representation that can be executed to restore the object. |
archive_1([env]) | Return (rep, args, imports). |
items() | Return all items to make object archivable. |
Bases: property
Attribute class: like property, but with default operators.
One way to use is to directly make a property with documentation and a default value:
x = attribute(default=1.0, doc=’x-coordinate’)
Another way is as a decorator:
@attribute def x(self):
‘x-coordinate’ return 1.0
Examples
>>> class Data(object):
... x = attribute(default=1.0, doc='x-coordinate')
... @attribute
... def y(self):
... 'y-coordinate'
... return -1.0
>>> d = Data()
>>> d.x
1.0
>>> d.x = 4
>>> d.x
4
>>> d.y
-1.0
>>> d.y = 2.0
>>> d.y
2.0
>>> help(d)
Help on Data in module ...:
class Data(__builtin__.object)
...
| x
| x-coordinate
|
| y
| y-coordinate
Methods
deleter | Descriptor to change the deleter on a property. |
getter | Descriptor to change the getter on a property. |
setter | Descriptor to change the setter on a property. |
Initialization.
Methods
deleter | Descriptor to change the deleter on a property. |
getter | Descriptor to change the getter on a property. |
setter | Descriptor to change the setter on a property. |
Initialization.
Bases: property
Parameter class: Turns a function into a parameter.
This has several benifits: 1) The docstring of the function describes the parameter. 2) The return value is used to initialize the parameter. 3) If the parameter is an instance of the class MemoizedContainer, then memoization is used and the signal _changed is sent when the parameter is modified.
>>> class Data(object):
... @parameter
... def x():
... "x coordinate" # Documentation
... return 10.0 # Default value
>>> d = Data()
>>> d.x
10.0
>>> d.x = 6
>>> d.x
6
If you want fast parameter access, use the dictionary directly: >>> d.__dict__[‘x’] 6
Methods
deleter | Descriptor to change the deleter on a property. |
getter | Descriptor to change the getter on a property. |
setter | Descriptor to change the setter on a property. |
Bases: property
Decorator for calculational functions that should be memoized. Memoization only happens with instances of MemoizedContainer.
>>> class Data(object):
... @calculate
... def f(x):
... "The square of x"
... return x**2
>>> d = Data()
>>> d.x = 6
>>> d.f
36
Methods
deleter | Descriptor to change the deleter on a property. |
getter | Descriptor to change the getter on a property. |
setter | Descriptor to change the setter on a property. |
Bases: dict
The paradigm for this class is that one has a set of parameters (call them x[0], x[1] etc.) and a set of functions that depend on these parameters (call them f[0], f[1] etc.). The idea is that the functions should compute the value only once and memoize it until the parameters that it depends on change.
To do this, define all the bare parameters using the parameter class. Then define all of the functions as standard functions with arguments that have the same name as the parameters. The argument list determines the dependencies. These should be defined as functions, and should not accept the parameter self. The actual member functions will be defined later by __new__.
If you would like to define helper functions that are not memoized, prefix them with an underscore.
>>> class Data1(MemoizedContainer):
... @parameter
... def x():
... "x coordinate" # Documentation
... return 10.0 # Default value
... @parameter
... def y():
... "y coordinate"
... return 2.0
... @parameter
... def z():
... "z coordinate"
... return -2.0
... @calculate
... def f(x):
... "The square of x"
... print "Computing f("+`x`+")"
... return x**2
... @calculate
... def g(x, f, y):
... "Product of x*f*y = x**3*y"
... print "Computing g("+`x`+", "+`f`+", "+`y`+")"
... tmp = x*f*y
... return tmp
>>> d = Data1(y=2.0)
>>> d.f # slow
Computing f(10.0)
100.0
>>> d.f # fast
100.0
>>> d.g # slow
Computing g(10.0, 100.0, 2.0)
2000.0
>>> d.g # fast
2000.0
>>> d.y = 3.0
>>> d.f # fast
100.0
>>> d.g # slow
Computing g(10.0, 100.0, 3.0)
3000.0
>>> d.g # fast
3000.0
>>> try: d.g = 5
... except AttributeError, err:
... print err
can't set attribute
>>> d.dependencies
{'y': set(['g']), 'x': set(['g', 'f']), 'z': set([]), 'g': set([]), 'f': set(['g'])}
One can also use multiple inheritance to combine parameters:
>>> class Data2(MemoizedContainer):
... @parameter
... def a():
... return -1.0 # Default value
... @parameter
... def b():
... return 2.0
... @calculate
... def h(a):
... print "Computing h("+`a`+")"
... return a**3
>>> class Data3(Data1, Data2):
... @parameter
... def c():
... return 2.0
... @calculate
... def F(c, f, g, h):
... print "Computing F("+`c`+", "+`f`+", "+`g`+", "+`h`+")"
... return c+f*g*h
>>> class Data(Data3):
... pass
>>> d = Data()
>>> d.F
Computing f(10.0)
Computing g(10.0, 100.0, 2.0)
Computing h(-1.0)
Computing F(2.0, 100.0, 2000.0, -1.0)
-199998.0
>>> d.g
2000.0
>>> d.F
-199998.0
For faster bare parameter access, use the dictionary
>>> d.x # slow
10.0
>>> d['x'] # fastest
10.0
Methods
clear | D.clear() -> None. Remove all items from D. |
copy | D.copy() -> a shallow copy of D |
fromkeys(...) | v defaults to None. |
get | D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None. |
has_key | D.has_key(k) -> True if D has a key k, else False |
items | D.items() -> list of D’s (key, value) pairs, as 2-tuples |
iteritems | D.iteritems() -> an iterator over the (key, value) items of D |
iterkeys | D.iterkeys() -> an iterator over the keys of D |
itervalues | D.itervalues() -> an iterator over the values of D |
keys | D.keys() -> list of D’s keys |
pop | D.pop(k[,d]) -> v, remove specified key and return the corresponding value. |
popitem | D.popitem() -> (k, v), remove and return some (key, value) pair as a |
setdefault | D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D |
update | D.update([E, ]**F) -> None. Update D from dict/iterable E and F. |
values | D.values() -> list of D’s values |
viewitems | D.viewitems() -> a set-like object providing a view on D’s items |
viewkeys | D.viewkeys() -> a set-like object providing a view on D’s keys |
viewvalues | D.viewvalues() -> an object providing a view on D’s values |
Bases: mmf.objects.parameter
>>> class A(object):
... x = option(doc='Description of member x',
... default=0)
... name = option(default='')
>>> a = A()
>>> a.x
0
>>> a.x = 1
>>> a.x
1
>>> a.x.__doc__
'Description of member x'
>>> a.name = "MyName"
>>> a.name.__doc__
'Undocumented Option'
Methods
deleter | Descriptor to change the deleter on a property. |
getter | Descriptor to change the getter on a property. |
setter | Descriptor to change the setter on a property. |
Bases: object
Options class. This class acts as a container. It provides methods to display the members. One can also define member functions, but their names must start with an underscore: all non-underscored names are assumed to be ‘options’.
The values defined in the base class are used as defaults. They will be deepcopied for each instance. Note that this means recursive data should not be used for parameters.
Use in conjunction with the option decorator to provide documentation for the options.
Examples
Here are some examples of direct usage:
>>> d1 = Options(['x', 'y', 'cc.x', 'cc.y'])
>>> d1.x = 3
>>> d1['y'] = 4
>>> d1.cc.x = 5
>>> d1.cc.y = 6
>>> d1
Options({'y': 4, 'x': 3, 'cc': Options({'y': 6, 'x': 5})})
>>> print d1
opts=Options(['x', 'y', 'cc.x', 'cc.y'])
opts.x=3
opts.y=4
opts.cc.x=5
opts.cc.y=6
You may define options with keywords too:
>>> d2 = Options(x=3, y=4)
>>> d2
Options({'y': 4, 'x': 3})
Here is an example which defines a base class with defaults:
>>> class MyOpts(Options):
... x = 1
... y = 2
... z = [2] # This will get copied
>>> c1 = MyOpts()
>>> c2 = MyOpts()
>>> c2.z[0] = 3
>>> print c1 # Note that z does not change here
opts=MyOpts(['x', 'y', 'z'])
opts.x=1
opts.y=2
opts.z=[2]
>>> print c2 # It only changes here.
opts=MyOpts(['x', 'y', 'z'])
opts.x=1
opts.y=2
opts.z=[3]
Here is an example with the option decorator:
>>> class MyOpts(Options):
... @option
... def abs_tol():
... 'Absolute tolerance'
... return 2e-16
...
... rel_tol = option(default=2e-8,
... doc='Relative tolerance')
>>> c1 = MyOpts()
>>> print c1
opts=MyOpts(['abs_tol', 'rel_tol'])
opts.abs_tol=2e-16
opts.rel_tol=2e-08
Bases: numpy.core.records.recarray
A simple subclass of the numpy recarray record array class that provides automatic conversion to a recarray. To subclass, simply define _names as a list of the field names and _array as a default array.
>>> from numpy import array
>>> class Coord(RecView):
... _array = array([1.0, 2.0])
... _names = ['x', 'y']
>>> c = Coord()
>>> c.x
array([ 1.])
Methods
all([axis, out]) | Returns True if all elements evaluate to True. |
any([axis, out]) | Returns True if any of the elements of a evaluate to True. |
argmax([axis, out]) | Return indices of the maximum values along the given axis. |
argmin([axis, out]) | Return indices of the minimum values along the given axis of a. |
argsort([axis, kind, order]) | Returns the indices that would sort this array. |
astype(t) | Copy of the array, cast to a specified type. |
byteswap(inplace) | Swap the bytes of the array elements |
choose(choices[, out, mode]) | Use an index array to construct a new array from a set of choices. |
clip(a_min, a_max[, out]) | Return an array whose values are limited to [a_min, a_max]. |
compress(condition[, axis, out]) | Return selected slices of this array along given axis. |
conj() | Complex-conjugate all elements. |
conjugate() | Return the complex conjugate, element-wise. |
copy([order]) | Return a copy of the array. |
cumprod([axis, dtype, out]) | Return the cumulative product of the elements along the given axis. |
cumsum([axis, dtype, out]) | Return the cumulative sum of the elements along the given axis. |
diagonal([offset, axis1, axis2]) | Return specified diagonals. |
dot(b[, out]) | Dot product of two arrays. |
dump(file) | Dump a pickle of the array to the specified file. |
dumps() | Returns the pickle of the array as a string. |
field(attr[, val]) | |
fill(value) | Fill the array with a scalar value. |
flatten([order]) | Return a copy of the array collapsed into one dimension. |
getfield(dtype, offset) | Returns a field of the given array as a certain type. |
item(*args) | Copy an element of an array to a standard Python scalar and return it. |
itemset(*args) | Insert scalar into an array (scalar is cast to array’s dtype, if possible) |
max([axis, out]) | Return the maximum along a given axis. |
mean([axis, dtype, out]) | Returns the average of the array elements along given axis. |
min([axis, out]) | Return the minimum along a given axis. |
newbyteorder([new_order]) | Return the array with the same data viewed with a different byte order. |
nonzero() | Return the indices of the elements that are non-zero. |
prod([axis, dtype, out]) | Return the product of the array elements over the given axis |
ptp([axis, out]) | Peak to peak (maximum - minimum) value along a given axis. |
put(indices, values[, mode]) | Set a.flat[n] = values[n] for all n in indices. |
ravel([order]) | Return a flattened array. |
repeat(repeats[, axis]) | Repeat elements of an array. |
reshape(shape[, order]) | Returns an array containing the same data with a new shape. |
resize(new_shape[, refcheck]) | Change shape and size of array in-place. |
round([decimals, out]) | Return a with each element rounded to the given number of decimals. |
searchsorted(v[, side]) | Find indices where elements of v should be inserted in a to maintain order. |
setasflat(arr) | Equivalent to a.flat = arr.flat, but is generally more efficient. |
setfield(val, dtype[, offset]) | Put a value into a specified place in a field defined by a data-type. |
setflags([write, align, uic]) | Set array flags WRITEABLE, ALIGNED, and UPDATEIFCOPY, respectively. |
sort([axis, kind, order]) | Sort an array, in-place. |
squeeze() | Remove single-dimensional entries from the shape of a. |
std([axis, dtype, out, ddof]) | Returns the standard deviation of the array elements along given axis. |
sum([axis, dtype, out]) | Return the sum of the array elements over the given axis. |
swapaxes(axis1, axis2) | Return a view of the array with axis1 and axis2 interchanged. |
take(indices[, axis, out, mode]) | Return an array formed from the elements of a at the given indices. |
tofile(fid[, sep, format]) | Write array to a file as text or binary (default). |
tolist() | Return the array as a (possibly nested) list. |
tostring([order]) | Construct a Python string containing the raw data bytes in the array. |
trace([offset, axis1, axis2, dtype, out]) | Return the sum along diagonals of the array. |
transpose(*axes) | Returns a view of the array with axes transposed. |
var([axis, dtype, out, ddof]) | Returns the variance of the array elements, along given axis. |
view([dtype, type]) |
x.__init__(...) initializes x; see help(type(x)) for signature
This class represents some data and values that must be calculated by a function calculate.
>>> class C(Calculator):
... @parameter
... def x(): return 1.0
... @parameter
... def y(): return 2.0
... def calculate(self):
... self.a = 2*self.x
... self.b = self.a*self.x*self.y
>>> class D(Calculator):
... @parameter
... def z(): return 3.0
... def calculate(self):
... self.c = self.z**3
>>> class E(C, D):
... def calculate(self):
... C.calculate(self)
... D.calculate(self)
>>> c = C()
>>> c.x = 2.0
>>> c.y = 3.0
>>> d = D(z=5.0)
>>> e = E(c, d)
>>> e.calculate()
>>> e.a
4.0
>>> e.b
24.0
>>> e.c
125.0
>>> e
E(y=3.0, x=2.0, z=5.0)
Methods
calculate() |
Return (results, wrap__init__). This is a class decorator to process the _state_vars attribute of cls and to define the documentation, and members _state_vars, _excluded_vars, _nodeps, _method_vars, _computed_vars, _vars, _defaults, and _dynamic.
Classes may perform additional processing if required by defining the classmethod() hooks _pre_hook_process_vars(cls) and _post_hook_process_vars(cls, results). The latter may modify the dictionary results.
Must be called in a subclass of StateVars.
Parameters : | copy : function, optional
archive_check : bool
with_docs : {None, interface, obj, list of obj}
|
---|---|
Returns : | results : dict
wrap__init__ : function
|
Examples
>>> class A(StateVars):
... "A simple class"
... _state_vars = [('a', 1, 'Param a'),
... ('b', 2, 'Param b'),
... ('c', Computed, 'A computed parameter'),
... ('c1', Computed(save=True),
... 'A saved computed parameter'),
... ('e', Excluded, 'An excluded parameter'),
... ('e1', Excluded(3), 'Excluded with default'),
... ('f', Excluded)]
... process_vars()
>>> print A.__doc__
A simple class
Usage: A(a=1, b=2)
Attributes
----------
**State Variables:**
a: Param a
b: Param b
**Computed Variables:**
c: A computed parameter
c1: A saved computed parameter
**Excluded Variables:**
e: An excluded parameter
e1: Excluded with default
f: <no description>
Return a class that is a subclass of array_.__class__ but that allows the elements to be accessed through a named member syntax.
For example, if array_ = array([1.0, 2.0]) and names = array([‘x’, ‘y’]) then c[0] == c.x, and c[1] == c.y
The preferred usage is to define a class which inherits from the returned class. The arguments will then defined the names and the default values for objects instantiated from this class. The advantage of proceeding this way is that the name of the class will be well defined and usefull rather than the generic “NamedArray”.
Examples
>>> from numpy import array
>>> a = array([0.0, 0.0, 0.0])
>>> n = array(['x', 'y', 'z'])
>>> class CoordArray(class_NamedArray(a, n)):
... pass
>>> c0 = CoordArray()
>>> c0
CoordArray([ 0., 0., 0.])
You can initialize the array from a sequence, and use keyword arguments to set specific values. If you do not initialize, then the default values are used. The initialization array need not be complete: it just initializes the first n values.
>>> c = CoordArray([1, 3], y=2)
>>> c
CoordArray([ 1., 2., 0.])
>>> (c.x, c.y)
(CoordArray([ 1.]), CoordArray([ 2.]))
>>> c.x = 3; c.y = 4
>>> print c
CoordArray(y=4.0, x=3.0, z=0.0)
Note that one may have repeated labels:
>>> a = array([[0, 0], [0, 0]])
>>> n = array([['x', 'y'], ['y', 'z']])
>>> class MatArray(class_NamedArray(a, n)):
... pass
>>> c = MatArray(x=1, y=2, z=3)
>>> c
MatArray([[1, 2],
[2, 3]])
>>> c.y
MatArray([2, 2])
>>> c.y = [4, 5]
>>> c
MatArray([[1, 4],
[5, 3]])
>>> a = array([0, 0, 0])
>>> n = array(['x', 'y', 'z'])
>>> class MatArray(class_NamedArray(a, n)):
... pass
>>> c = MatArray(vals=[1, 2, 3])
>>> c
MatArray([1, 2, 3])
>>> c.t = 6
>>> c.t
6
Return a view of a as a recarray with defined field names.
>>> from numpy import array
>>> a = array([[1, 2, 3], [4, 5, 6]])
>>> r = recview(a, ['x', 'y', 'z'])
>>> print r
[[(1, 2, 3)]
[(4, 5, 6)]]
>>> r.x = 0
>>> a
array([[0, 2, 3],
[0, 5, 6]])