Organizing Python classes in modules and/or packages
I like the Java convention of having one public class per file, even if there are sometimes good reasons to put more than one public class into a single file. In my case I have alternative implementations of the same interface. But if I would place them into separate files, I'd have redundant names in the import statements (or misleading module names):
import someConverter.SomeConverter
whereas someConverter
would be the file (and module) name and SomeConverter
开发者_运维百科the class name. This looks pretty inelegant to me. To put all alternative classes into one file would lead to a more meaningful import statement:
import converters.SomeConverter
But I fear that the files become pretty large, if I put all related classes into a single module file. What is the Python best practise here? Is one class per file unusual?
A lot of it is personal preference. Using python modules, you do have the option to keep each class in a separate file and still allow for import converters.SomeConverter
(or from converters import SomeConverter
)
Your file structure could look something like this:
* converters
- __init__.py
- baseconverter.py
- someconverter.py
- otherconverter.py
and then in your __init__.py
file:
from baseconverter import BaseConverter
from otherconverter import OtherConverter
Zach's solution breaks on Python 3. Here is a fixed solution.
A lot of it is personal preference. Using python modules, you do have the option to keep each class in a separate file and still allow for import converters.SomeConverter
(or from converters import SomeConverter
)
Your file structure could look something like this:
* converters
- __init__.py
- baseconverter.py
- someconverter.py
- otherconverter.py
and then in your __init__.py
file:
from converters.baseconverter import BaseConverter
from converters.otherconverter import OtherConverter
The above solutions are good, but the problem with importing modules in __init__.py
is that this will cause all the modules to be loaded twice(inefficient). Try adding a print statement at the end of otherconverter.py
and run otherconverter.py
. (You'll see that the print statement is executed twice)
I prefer the following. Use another package with name "_converter" and define everything there. And then your "converters.py" becomes the interface for accessing all public members
* _converters
- __init__.py
- baseconverter.py
- someconverter.py
- otherconverter.py
* converters.py
where converters.py
is
from _converters.someconverter import SomeConverter
from _converters.otherconverter import OtherConverter
...
...
...
converters = [SomeConverter, OtherConverter, ...]
And as the previous solutions mentioned, it is a personal choice. A few practices involve defining a module "interace.py" within the package and importing all public members here. If you have many modules to load, you should choose efficiency over aesthetics.
精彩评论