Reputation: 7925
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?
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
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
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
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
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