tags:

views:

152

answers:

4

Python's lack of static typing makes it possible to use and rely on classes without importing them. Should you import them anyway? Does it matter?

Example

someclass.py

class SomeClass:
    def __init__(self, some_value):
        self.some_value = some_value

someclient.py

class SomeClient:
    def __init__(self, some_class_instance):
        self.some_class_helper = some_class_instance

Here, the functionality of SomeClient clearly relies on SomeClass or at least something that behaves like it. However, someclient.py will work just fine without import someclass. Is this ok? It feels wrong to use something without saying anywhere that you're even using it.

+5  A: 

Importing SomeClass won't make any difference to how that code works.

If you're worried about making the code understandable, comment the fact that SomeClient expects a SomeClass instance, and/or document it in the docstring.

If you want to police the fact that SomeClient requires a SomeClass instance, you can assert it:

class SomeClient:
    def __init__(self, some_class_instance):
        assert isinstance(some_class_instance, SomeClass)
        self.some_class_helper = some_class_instance

which will require importing SomeClass. But note that you're being rather restrictive there - it precludes using a Mock SomeClass for testing purposes, for example. (There's a lengthy rant about this here: "isinstance() considered harmful".)

RichieHindle
I'm definitely not interested in type checking or policing the argument.
Daniel Straight
@Daniel: Good! It usually is a bad practice anyway. Prevents code reuse and duck-typing
nosklo
+6  A: 

Yes, it's completely ok. some_class_instance might be anything, it doesn't have to be an instance of SomeClass. You might want to pass an instance that looks just like SomeClass, but uses a different implementation for testing purposes, for example.

Lukáš Lalinský
+1: Only import what you actually use. What happens at run time is often an extension of something you imported. Don't fuss with "import everything to make a static language out of Python". Instead, use the dynamic nature of Python correctly.
S.Lott
+4  A: 

In this case, you shouldn't import the class.

Python relies on what is called "duck typing" - if it walks like a duck and quacks like a duck, it might as well be a duck.

Your code doesn't care what class really gets passed in when the program runs. All it cares is that it acts just like "SomeClass" acts.

duck-typing

A pythonic programming style which determines an object’s type by inspection of its method or attribute signature rather than by explicit relationship to some type object (“If it looks like a duck and quacks like a duck, it must be a duck.”) By emphasizing interfaces rather than specific types, well-designed code improves its flexibility by allowing polymorphic substitution. Duck-typing avoids tests using type() or isinstance(). (Note, however, that duck-typing can be complemented with abstract base classes.) Instead, it typically employs hasattr() tests or EAFP programming.

Tom Leys
+1  A: 

This is a good python code, "we are all consenting adults here", maybe if you expect a class you should include a comment and that's ok.

pygabriel