tags:

views:

35

answers:

4

Hello, I am just starting to learn Python, but I have already run into some errors. I have made a file called pythontest.py with the following contents:

class Fridge:
    """This class implements a fridge where ingredients can be added and removed individually
       or in groups"""
    def __init__(self, items={}):
        """Optionally pass in an initial dictionary of items"""
        if type(items) != type({}):
            raise TypeError("Fridge requires a dictionary but was given %s" % type(items))
        self.items = items
        return

I want to create a new instance of the class in the interactive terminal, so I run the following commands in my terminal: python3

>> import pythontest
>> f = Fridge()

I get this error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'Fridge' is not defined

The interactive console cannot find the class I made. The import worked successfully, though. There were no errors.

+1  A: 

Try

import pythontest
f=pythontest.Fridge()

When you import pythontest, the variable name pythontest is added to the global namespace and is a reference to the module pythontest. To access objects in the pythontest namespace, you must preface their names with pythontest followed by a period.

import pythontest the preferred way to import modules and access objects within the module.

from pythontest import *

should (almost) always be avoided. The only times when I think it is acceptable is when setting up variables inside a package's __init__, and when working within an interactive session. Among the reasons why from pythontest import * should be avoided is that it makes it difficult to know where variables came from. This makes debugging and maintaining code harder. It also doesn't assist mocking and unit-testing. import pythontest gives pythontest its own namespace. And as the Zen of Python says, "Namespaces are one honking great idea -- let's do more of those!"

unutbu
A: 

You're supposed to import the names, i.e., either

 import pythontest
 f= pythontest.Fridge()

or,

from pythontest import *
f = Fridge()
highBandWidth
+2  A: 

You need to do:

>>> import pythontest
>>> f = pythontest.Fridge()

Bonus: your code would be better written like this:

def __init__(self, items=None):
    """Optionally pass in an initial dictionary of items"""
    if items is None:
         items = {}
    if not isinstance(items, dict):
        raise TypeError("Fridge requires a dictionary but was given %s" % type(items))
    self.items = items
SilentGhost
Just curious, why is items={} in the parameter list a bad idea?
RevolXadda
@RevolXadda: Because function arguments are only processed once. If you give it something mutable, it will mutate between function calls (if you mutate it). Observe the output of `def foo(d=[]): d.append('foo'); print d` when you call it multiple times in a row.
Daenyth
@Daenyth: Thank you! I'd completely forgotten about that.
RevolXadda
Haha, I was actually using a book, and that was one of the examples. Do you recommend any tutorials for Python so I do not start with bad habits?
Kelp
@Kelp: http://docs.python.org/ particularly tutorial and howtos there, and the library reference of course and http://stackoverflow.com/tags/python/faq
SilentGhost
+2  A: 

No one seems to mention that you can do

from pythontest import Fridge

That way you can now call Fridge() directly in the namespace without importing using the wildcard

Falmarri