[Tutor] Question about writing to Excel with slavic characters

Walter Prins wprins at gmail.com
Fri Mar 9 11:49:35 CET 2012


Hi Marko,

On 9 March 2012 08:34, Marko Limbek <marko.limbek at valicon.net> wrote:
>  File "C:\Dropbox\Exc_MarkoL_Zenel\Python\crosstabs\src\src\rw.py",
> line 715, in <module>
>    mySavReaderObject.getNumberofVariables(savFileName,
> mySavReaderObject.fh, mySavReaderObject.spssio)
> AttributeError: 'SavReader' object has no attribute 'spssio'
>
> So the methods must really be somewhat internal.

Python doesn't enforce access levels like some other languages do
which means effectively, any member of any object can in principle be
accessed.  By "gentlemans agreement", members with a name starting
with a single underscore are supposed to be considered private
(although you can still ignore this agreement and access them anyway)
while members with double underscores get some behind the scenes
assistance to ensure privateness and name uniqueness via "name
mangling".  (There's a couple of other minor behavioural differences,
but the point stands -- there's no preventing you as programmer from
accessing "private" members of a class if you insist to do so.  But
then it's doubly your problem if that gets you into trouble ;) )

Anyway, the message then really means what it says -- The SavReader
object instance you're using really does not have an spssio member
(there should be no problem accessing it if it was there so I must
interpret that message to mean what it says.)   I'm not sure why this
would be the case -- perhaps we're not looking/using the same version
of the reader class and the member name has changed?  (I previously
guessed/assumed  that you were using the following version, or
something close enough to it, given here:
http://code.activestate.com/recipes/577650-python-reader-for-spss-sav-files/
  Looking back I see you're actually using a slightly newer version
from here: http://code.activestate.com/recipes/577811-python-reader-writer-for-spss-sav-files-linux-mac-/
But, everything I've said appears to still hold true about the updated
version, so can you clarify which version you're currently using?)

Regardless, the error simple enough to troubleshoot -- have a look at
*your* version of the SavReader class, and find out what the member
name should in fact be.  There are calls to e.g.
getNumberofVariables() in the class itself, from which you can
determine what the object data/field/variable member is that holds the
value to pass to the spssio parameter of getNumberofVariables().

But, I have to repeat: The value that you get from
getNumberofVariables() is the exact same value that you get inside of
the numVars variable after calling:

  numVars, nCases, varNames, varTypes, printTypesFile,
printTypeLabels, varWids = mySavReaderObj.getSavFileInfo()

You can see this will be the case if you read the code:
1) The __init__ method assigns self.numVars_ from the result of
calling self._readBasicSavFileInfo().
2) This in turn calls on self.getNumberofVariables() as follows:
  numVars = self.getNumberofVariables(self.fh, self.spssio)[1]
... and that local variable numVars is what is returned and ends up in
the object member self.numVars_.
3) Then, looking at getSavFileInfo() you can see that it in turn
simply returns self.numVars_,
4) In other words it returns the same value that it previously
retrieved using self.getNumberofVariables().

So, the 2 ways are functionally identical w.r.t. the retrieval of the
"NumberofVariables".  The only differences are that a) with the latter
call you get a bunch of other stuff besides the number of variables,
and b) With the latter call you don't have to worry about spssio or fh
parameters (because they're absent/not required when calling
getSavFileInfo() and c) with the latter call the actual retrieval of
the number of variables happened slightly earlier on when the
SavReader object was created, while with the direct call to
getNumberofVariables() it is presumably read again directly from the
file.

So, I think you need to stop fixating on the getNumberofVariables()
method as it's not, I suspect, the solution to your real problem like
you seem to think, and it is also introducing a distraction (the
parameters issue) since it's not really the intended way for you to
use this class.  (Not that you absolutely cannot use it if you're
determined to do so, as I've already tried to explain, but it's just
probably just easier to go with the intended means of use for now
given that there's functionally no difference in the result up to this
point, at least that I can see.)

Walter


More information about the Tutor mailing list