Instance Hunter
Instance Hunter

Reputation: 7925

Should you import all classes you use in Python?

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.

Upvotes: 3

Views: 291

Answers (4)

pygabriel
pygabriel

Reputation: 10008

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.

Upvotes: 1

Tom Leys
Tom Leys

Reputation: 19029

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.

Upvotes: 4

Lukáš Lalinský
Lukáš Lalinský

Reputation: 41306

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.

Upvotes: 9

RichieHindle
RichieHindle

Reputation: 281505

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".)

Upvotes: 6

Related Questions