29 INSTANCE_ARGUMENT =
"instance"
32 """Inherit this class to give yourself a python class that wraps a set of
33 functions that together constitute the methods of the class.
35 The method functions must all have as a first argument an object
36 holding the instance data. There must also be a function that
37 returns a new instance of the class, the constructor.
39 Your subclass must define
40 _module - The module where the method functions, including the
41 constructor can be found
42 _new_instance - The name of a function that serves as a constructor,
43 returning the instance data.
45 To access the instance data, use the read-only property instance.
47 To add some functions from _module as methods, call classmethods like
48 add_method and add_methods_with_prefix.
50 def __new__(cls, *args, **kargs):
55 return super(ClassFromFunctions, cls).__new__(cls)
58 """Construct a new instance, using either the function
59 self._module[self._new_instance] or using existing instance
60 data. (specified with the keyword argument, instance)
62 Pass the arguments that should be passed on to
63 self._module[self._new_instance] . Any arguments of that
64 are instances of ClassFromFunctions will be switched with the instance
65 data. (by calling the .instance property)
67 if INSTANCE_ARGUMENT
in kargs:
70 self.
__instance = getattr(self._module, self._new_instance)(
71 *process_list_convert_to_instance(args) )
74 """Get the instance data.
76 You can also call the instance property
80 instance = property(get_instance)
86 """Add the function, method_name to this class as a method named name
88 def method_function(self, *meth_func_args):
89 return getattr(self._module, function_name)(
91 *process_list_convert_to_instance(meth_func_args) )
93 setattr(cls, method_name, method_function)
94 setattr(method_function,
"__name__", method_name)
95 return method_function
99 """Add the function, method_name to this class as a classmethod named name
101 Taken from function_class and slightly modified.
103 def method_function(self, *meth_func_args):
104 return getattr(self._module, function_name)(
106 *process_list_convert_to_instance(meth_func_args) )
108 setattr(cls, method_name, classmethod(method_function))
109 setattr(method_function,
"__name__", method_name)
110 return method_function
114 """Add the function, method_name to this class as a method named name
116 Taken from function_class and slightly modified.
118 def method_function(self, *meth_func_args):
119 return getattr(self._module, function_name)(
121 *process_list_convert_to_instance(meth_func_args) )
123 setattr(cls, method_name, method_function)
124 setattr(method_function,
"__name__", method_name)
125 return method_function
129 """Add a group of functions with the same prefix
131 for function_name, function_value, after_prefix
in \
132 extract_attributes_with_prefix(cls._module, prefix):
133 cls.add_method(function_name, after_prefix)
137 """Add a group of functions with the same prefix, and set the
138 _new_instance attribute to prefix + constructor
140 cls.add_methods_with_prefix(prefix)
141 cls._new_instance = prefix + constructor
144 def decorate_functions(cls, decorator, *args):
145 for function_name
in args:
146 setattr( cls, function_name,
147 decorator( getattr(cls, function_name) ) )
149 def method_function_returns_instance(method_function, cls):
150 """A function decorator that is used to decorate method functions that
151 return instance data, to return instances instead.
153 You can't use this decorator with @, because this function has a second
156 assert(
'instance' == INSTANCE_ARGUMENT )
157 def new_function(*args):
158 kargs = { INSTANCE_ARGUMENT : method_function(*args) }
159 if kargs[
'instance'] ==
None:
162 return cls( **kargs )
166 def method_function_returns_instance_list(method_function, cls):
167 def new_function(*args):
168 return [ cls( **{INSTANCE_ARGUMENT: item} )
169 for item
in method_function(*args) ]
172 def methods_return_instance_lists(cls, function_dict):
173 for func_name, instance_name
in function_dict.iteritems():
174 setattr(cls, func_name,
175 method_function_returns_instance_list(
176 getattr(cls, func_name), instance_name))
178 def default_arguments_decorator(function, *args):
179 """Decorates a function to give it default, positional arguments
181 You can't use this decorator with @, because this function has more
184 def new_function(*function_args):
185 new_argset = list(function_args)
186 new_argset.extend( args[ len(function_args): ] )
187 return function( *new_argset )
190 def return_instance_if_value_has_it(value):
191 """Return value.instance if value is an instance of ClassFromFunctions,
194 if isinstance(value, ClassFromFunctions):
195 return value.instance
199 def process_list_convert_to_instance( value_list ):
200 """Return a list built from value_list, where if a value is in an instance
201 of ClassFromFunctions, we put value.instance in the list instead.
203 Things that are not instances of ClassFromFunctions are returned to
204 the new list unchanged.
206 return [ return_instance_if_value_has_it(value)
207 for value
in value_list ]
209 def extract_attributes_with_prefix(obj, prefix):
210 """Generator that iterates through the attributes of an object and
211 for any attribute that matches a prefix, this yields
212 the attribute name, the attribute value, and the text that appears
213 after the prefix in the name
215 for attr_name, attr_value
in obj.__dict__.iteritems():
216 if attr_name.startswith(prefix):
217 after_prefix = attr_name[ len(prefix): ]
218 yield attr_name, attr_value, after_prefix
220 def methods_return_instance(cls, function_dict):
221 """Iterates through a dictionary of function name strings and instance names
222 and sets the function to return the associated instance
224 for func_name, instance_name
in function_dict.iteritems():
225 setattr(cls, func_name,
226 method_function_returns_instance( getattr(cls, func_name), instance_name))
def add_methods_with_prefix
def add_constructor_and_methods_with_prefix