I have a class with a large number of attributes; I would like to present them grouped (rather than in a flat list), with a section-like appearance inside the class documentation.
Is this possible with docutils/sphinx? Any suggestion to achieve something visually similar, perhaps by inserting dummy attributes?
Regular reST section headings do not work (see this fairly recent mailing list thread, and also this older thread), but the .. rubric:: directive can be used as a heading in docstrings. Perhaps you can use something like this:
class MyClass(object):
"""
.. rubric:: Class variables
:cvar foo: foo documentation
:cvar bar: bar documentation
.. rubric:: Instance variables
:ivar baz: baz documentation
"""
pass
Related
I have a hierarchy of data that i would like to build using classes instead of hard coding it in. The structure is like so:
Unit (has name, abbreviation, subsystems[5 different types of subsystems])
Subsystem ( has type, block diagram(photo), ParameterModel[20 different sets of parameterModels])
ParameterModel (30 or so parameters that will have [parameter name, value, units, and model index])
I'm not sure how to do this using classes but what i have made kindof work so far is creating nested dictionaries.
{'Unit':{'Unit1':{'Subsystem':{'Generator':{Parameter:{'Name': param1, 'Value':1, 'Units': 'seconds'}
like this but with 10-15 units and 5-6 subsystems and 30 or so parameters per subsystem. I know using dictionaries is not the best way to go about it but i cannot figure out the class sharing structure or where to start on building the class structure.
I want to be able to create, read, update and delete, parameters in a tkinter gui that i have built as well as export/import these system parameters and do calculations on them. I can handle the calculations and the import export but i need to create classes that will build out this structure and be able to reference each individual unit/subsystem/parameter/value/etc
I know thats alot but any advice? ive been looking into the factory and abstract factory patterns in hope to try and figure out how to create the code structure but to no avail. I have experience with matlab, visual basic, c++, and various arduio projects so i know most basic programming but this inheritance class structure is something i cannot figure out how to do in an abstract way without hardcoding each parameter with giant names like Unit1_Generator_parameterName_parameter = ____ and i really dont want to do that.
Thanks,
-A
EDIT: Here is one way I've done the implementation using a dictionary but i would like to do this using a class that can take a list and make a bunch of empty attributes and have those be editable/callable generally like setParamValue(unit, susystem, param) where i can pass the unit the subsystem and then the parameter such as 'Td' and then be able to change the value of the key,value pair within this hierarchy.
def create_keys(list):
dict = {key: None for key in list}
return dict
unit_list = ['FL','ES','NN','SF','CC','HD','ND','TH'] #unit abbreviation
sub_list = ['Gen','Gov','Exc','PSS','Rel','BlkD']
params_GENROU = ["T'do","T''do","T'qo","T''qo",'H','D','Xd','Xq',"Xd'","Xq'","X''d=X''q",'Xl','S(1.0)','S(1.2)','Ra'] #parameter names
dict = create_keys(unit_list)
for key in dict:
dict[key] = create_keys(sub_list)
dict[key]['Gen'] = create_keys(params_GENROU)
and inside each dict[unit][Gen][ParamNames] there should be a dict containing Value, units(seconds,degrees,etc), description and CON(#basically in index for another program we use)
In a python project I generate autoapi documntation. Special comment appear in generated html files.
For instance it's working and displaying on final html page:
def do_action(self,params):
"""
This is function to do some cool stuffs.
Actually it should
"""
pass
Or
...
applicationConfig = None
"""This variable hold some important data"""
However I would like autoapi generate some custom comment into html page
For example I've got a comment in code like this:
"""These are public variable:"""
p_var1 = "segg"
p_var2 = "fos"
But this last comment not shown in generated documentation. Maybe because it hasn't connected to any definition structure in source code? (I mean neither variable declaration nor function or class declaration)
Anyway, how should force sphinx to generate html entry from any comments arrounded by triple apostrophe?
There are two options for having sphinx parse variable comments. The first is via attribute docstrings, which are specified in pep 224 to belong below the attribute that they describe, as in your first example. While it was rejected, it is the format sphinx requires in order to work correctly:
p_var1 = "segg"
"""Docstring for p_var1"""
Renders as:
Alternatively, sphinx will also pick up comments above the attribute that start with a colon and treat them like a docstring, which in some cases looks a bit better in the source code:
#: Description for p_var1
p_var1 = "segg"
Renders also as:
There is no option to pick up a comment without a module, exception, class, method, function, or variable being attached to it, becauseautodoc explicitly only considers information from docstrings (and call signatures, but that's the only exception).
MyClass is derived from "list": MyClass(list)
I would like to document MyClass nicely.
Unfortunately, when trying help(MyClass),
I get my own documentation, but I also get a lot of stuff about "list".
Would there be a simple way to control that?
I read something about metaclasses, but I was unable to do something.
Thanks for your suggestions,
Michel
Well, that is what help does. It introspects into your class and show the name and the associated __doc__ for each callable attribute in the class, and that is not customizable.
Attributes of the superclass are considered attributes of the class, and are reached in the introspection Python's help do.
Metaclasses could even be used to customize the output one gets when he does "dir" on your class - but they do not change the output of the help text. To change "dir" output, create a metaclass implementing a __dir__ method, and return a list of what you want visible as dir's output.
class M(type):
def __dir__(self):
return [] # blank dir contents
class MyList(list, metaclass=M):
...
On the other hand, the help contents displayed for list attributes are not that verbose, and can actually be helpful - if you override any methods to do something different than described, the incorrect text won't show anyway. So you might just live with it.
Another tip is that instead of subclassing list you might prefer to subclass collections.abc.MutableSequence instead, and use an inner agregated (normal) list to keep your data: that will require you to implement a lot less methods to have your class working properly as a sequence and is preferable in most cases to subclass list. That won't change help's verbosity though.
(All in ActivePython 3.1.2)
I tried to change the class (rather than instance) attributes. The __dict__ of the metaclass seemed like the perfect solution. But when I tried to modify, I got:
TypeError: 'dict_proxy' object does
not support item assignment
Why, and what can I do about it?
EDIT
I'm adding attributes inside the class definition.
setattr doesn't work because the class is not yet built, and hence I can't refer to it yet (or at least I don't know how).
The traditional assignment doesn't work because I'm adding a large number of attributes, whose names are determined by a certain rule (so I can't just type them out).
In other words, suppose I want class A to have attributes A.a001 through A.a999; and all of them have to be defined before it's fully built (since otherwise SQLAlchemy won't instrument it properly).
Note also that I made a typo in the original title: it's __dict__ of a regular class, not a metaclass, that I wanted to modify.
The creation of a large number of attributes following some rule smells like something is seriously wrong. I'd go back and see if there isn't a better way of doing that.
Having said there here is "Evil Code" (but it'll work, I think)
class A:
locals()['alpha'] = 1
print A.alpha
This works because while the class is being defined there is a dictionary that tracks the local variables you are definining. These local variables eventually become the class attributes. Be careful with locals as it won't necessarily act "correctly." You aren't really supposed to be modifying locals, but it does seem to work when I tried it.
Instead of using the declarative syntax, build the table seperately and then use mapper on it. see http://www.sqlalchemy.org/docs/05/ormtutorial.html# I think there is just no good way to add computed attributes to class while defining it.
Alternatively, I don't know whether this will work but:
class A(object):
pass
A.all_my_attributes = values
class B(declarative_base, A):
pass
might possibly work.
I'm not too familiar with how 3 treats dict but you might be able to circumvent this problem by simply inheriting the dictionary class like so:
class A(dict):
def __init__(self,dict_of_args):
self['key'] = 'myvalue'
self.update(dict_of_args)
# whatever else you need to do goes here...
A() can be referenced like so:
d = {1:2,3:4}
obj = A(mydict)
print obj['test'],obj[3] # this will print myvalue and 4
Hope this helps.
I want to see if I can map Racket structure fields to columns in a DB.
I've figured out how to extract accessor functions from structures in PLT scheme using the fourth return value of:
(struct-type-info)
However the returned procedure indexes into the struct using an integer. Is there some way that I can find out what the field names were at point of definition? Looking at the documentation it seems like this information is "forgotten" after the structure is defined and exists only via the generated-accessor functions: (<id>-<field-id> s).
So I can think of two possible solutions:
Search the namespace symbols for ones that start with my struct name (yuk);
Define a custom define-struct macro that captures the ordered sequence of field-names inside some hash that is keyed by struct name (eek).
I think something along the lines of 2. is the right approach (define-struct has a LOT of knobs and many don't make sense for this) but instead of making a hash, just make your macro expand into functions that manipulate the database directly. And the syntax/struct library can help you do the parsing of the define-struct form.
The answer depends on what you want to do with this information. The thing is that it's not kept in the runtime -- it's just like bindings in functions which do not exist at runtime. But they do exist at the syntax level (= compile-time). For example, this silly example will show you the value that is kept at the syntax level that contains the structure shape:
> (define-struct foo (x y))
> (define-syntax x (begin (syntax-local-value #'foo) 1))
> (define-syntax x (begin (printf ">>> ~s\n" (syntax-local-value #'foo)) 1))
>>> #<checked-struct-info>
It's not showing much, of course, but this should be a good start (you can look for struct-info in the docs and in the code). But this might not be what you're looking for, since this information exists only at the syntax level. If you want something that is there at runtime, then perhaps you're better off using alists or hash tables?
UPDATE (I've skimmed too quickly over your question before):
To map a struct into a DB table row, you'll need more things defined: at least hold the DB and the fields it stand for, possibly an open DB connection to store values into or read values from. So it looks to me like the best way to do that is via a macro anyway -- this macro would expand to a use of define-struct with everything else that you'd need to keep around.