Python … grrrr

Hacking up some python classes and object bits for a project. Honestly, this would be soooooo much easier in Perl, but for a number of reasons, the person started it in Python. So we are trying to contribute.

And I am running into some of the more joyous elements of python. Such as completely inane error messages which tell you next to zero about what the real problem is.

Thankfully, I have google. And google is my friend.

I especially like these:

TypeError: 'module' object is not callable

and when you google it, you discover that it is actually some sort of naming error.

This is coming in from a


Size = size_util()

call with a file named size_util.py in the appropriate library and the requisite


from X import size_util

in the main.py

The class …


class size_util(object):
"""
An encapsulation of the sizing/scaling methods.
"""

def __init__(self):
self.data = {}
self.Units = 'SI'
self.Scale = \
{
'IEC': {
'B': 2 ** 0,
'KiB': 2 ** 10,
'MiB': 2 ** 20,
'GiB': 2 ** 30,
'TiB': 2 ** 40,
'PiB': 2 ** 50,
'EiB': 2 ** 60,
'ZiB': 2 ** 70,
'YiB': 2 ** 80

},

'SI': {
'B': 10 ** 0,
'KB': 10 ** 3,
'MB': 10 ** 6,
'GB': 10 ** 9,
'TB': 10 ** 12,
'PB': 10 ** 15,
'EB': 10 ** 18,
'ZB': 10 ** 21,
'YB': 10 ** 24
},

'Chemistry': { 'Mole': 6.02214078 * (10 ** 23) }
# a mole of something is a fairly huge amount of it
# not that we are going to start talking about pico-Mole of Bytes
# as being anything less than huge (its in the 6 PB region)
# ...
}
# use a regex for the size, as the size could be expressed
# by this Perl version of
# a regex (\d+\.{0,1}\d+)\s{0,}([KMGTPE]{0,1}i{0,1}B{0,1})
self.size_value = re.compile('(\d+\.{0,1}\d+)\s{0,}[KMGTPE]{0,1}i{0,1}B{0,1}',flags=re.I)
self.size_units = re.compile('\d+\.{0,1}\d+\s{0,}([KMGTPE]{0,1}i{0,1}B{0,1})',flags=re.I)

Egad.

I am guessing that a nice simple “locate libraries here” function is whats needed. Or something like that.

[update] this is why I don’t like poor design.

I made a model of the problem. Here’s the whole code: in file d.py

#!/opt/python/2.7.3/bin/python

import s

Size    = s()

print "size of 27.3GB = ", Size.get_real_size("27.3GB")

and now file s.py

class s(object):
    
    def __init__(self):             
        self.data = {}
        print "hi from s\n"

With this code in my debugger (Komodo from ActiveState ROCKS!), I kept getting the error. I inserted PYTHONPATH bits, etc. Google was next to useless. Finally found it though, down in the google land.

The initialization call is to FILENAME.CLASS, not to CLASS.

So its not


Size = s()

but


Size = s.s()

Um. Ok. Can’t tell you how many manuals I googled for that one.

Perl does this, a wee bit more intelligently. Gaaak.

FWIW, I am effectively grafting functionality I’ve written long ago into someone elses project. I wrote it in Perl, its nice and compact, it works, and is easy to understand. I created a nice set of modules out of it, SI::Utils, that we use in our code. This new code needs it, so I am adapting our library to Python.

Viewed 42792 times by 6015 viewers

One thought on “Python … grrrr

  1. Another way to look at your updated example it is that ‘import s’ here parses s.py s and places its contents in the module named s (consider it a namespace); ‘import s as y’ parses s.py and places its contents in the module (or namespace) named y.

    Perhaps the second approach would have made things clearer. If you wanted the class named s from a namespace that was called ‘y’, you wouldn’t have called y(), you would have called y.s(). The file s.py can define multiple classes, having one of them named the same as the file (like class s is in s.py) doesn’t give it special behavior.

    Or if you don’t want/need the namespaces for a small tool, use ‘from s import *’ (With the same caveats as “using namespace std” from c++ land — know why and where you’re doing it.)

    I agree the error message is terse, but it is saying the right thing; the module name itself isn’t callable. It would be nice if it suggested alternatives (“the available objects with () defined in the module s are s.s, s.foo, and s.bar; perhaps you wanted one of those.”)

    Just my 2c…

    And, for reference for the next google searcher, this is officially explained here: http://docs.python.org/tutorial/modules.html

Comments are closed.