Why do only callable objects get a __name__?

John Ladasky john_ladasky at sbcglobal.net
Tue Nov 19 01:10:11 EST 2013


On Monday, November 18, 2013 3:37:03 PM UTC-8, Steven D'Aprano wrote:
> On Mon, 18 Nov 2013 13:02:26 -0800, John Ladasky wrote:
> 
> > I am implementing a state machine.  The outputs of the various states in
> > the machine have variable contents.  I started by making dictionaries
> > for each state output, but I soon tired of the bracket-and-quote-mark
> > syntax for referring to the contents of these state output dictionaries.
> >  That's why I am switching to named tuples.  It doesn't affect the
> > __name__ issue, since dictionaries also cannot be called.
> >
> > I want to capture the names of the executed states in a record of the
> > state machine's history.  This information is already encoded in the
> > namedtuple's type.
> 
> 
> I find this rather confusing. Does every state have it's own unique 
> namedtuple class?

Yes.  The state machine trains neural networks.  There are various states which are executed in various orders -- generating a new network variant, calculating a local error gradient, taking a (variable size and curvature sensitive) step down the gradient, and then, possibly repeating.

I want to watch this neural network training process run, in part to debug it.  At the end of each state execution, I use a SINGLE, all-purpose function hook in the main loop to print the result.  Every state result namedtuple is also saved in a list called "history".  I sometimes need information from the first state executed, or the most recent state, or even two states back, to choose the next state transition.

At some point in the future, I can override the print function in the main loop, and have a GUI intercept the output as it is generated.

Many of the parameters returned are common to all states, but quite a few are not.  By stepping through the namedtuple's "_fields" and picking out a few special cases, I can get output like this:

=================================================

== START ==

action : START
time : 0.203123
net :
  0.   0.   0.
  0.   0.   0.   0.
full_err : 0.766030
train_err : 0.780680
validate_err : 0.750036
next_state : VARIANT


== VARIANT ==

action : VARIANT
time : 0.000058
net :
 1.0356 -0.1986 -1.7067
-1.0545  1.7081  0.4573 -1.0968
next_state : GRADIENT


== GRADIENT ==

action : GRADIENT
time : 0.094384
net :
 1.0356 -0.1986 -1.7067
-1.0545  1.7081  0.4573 -1.0968
grad :
[[-0.0047 -0.0034 -0.0001  0.    ]
 [ 0.01    0.0069 -0.003   0.0085]]
train_err : 1.226932
incrmag : 0.001000
normag : 0.010000
next_state : LEAP


== LEAP ==

action : LEAP
time : 0.048523
net :
 0.9882 -0.2328 -1.7079
-0.9545  1.7774  0.4271 -1.0115
curvature : concave
leap : 10.000000
train_err : 1.118779
incrmag : 0.001000
normag : 0.010000
next_state : GRADIENT


== GRADIENT ==

action : GRADIENT
time : 0.092888
net :
 0.9882 -0.2328 -1.7079
-0.9545  1.7774  0.4271 -1.0115
grad :
[[-0.0037 -0.0027  0.0004  0.    ]
 [ 0.01    0.0068 -0.0043  0.0092]]
train_err : 1.118779
incrmag : 0.001000
normag : 0.010000
next_state : LEAP

[etc.]

=================================================

I'm probably making this sound more complicated than it is.  A good object and data structure will make my system run cleanly and flexibly.  I feel like I'm already half-way there.



More information about the Python-list mailing list