65

Possible Duplicate:
How many Python classes should I put in one file?

Coming from a C++ background I've grown accustomed to organizing my classes such that, for the most part, there's a 1:1 ratio between classes and files. By making it so that a single file contains a single class I find the code more navigable. As I introduce myself to Python I'm finding lots of examples where a single file contains multiple classes. Is that the recommended way of doing things in Python? If so, why?

Am I missing this convention in the PEP8?

martineau
  • 119,623
  • 25
  • 170
  • 301
Karim
  • 18,347
  • 13
  • 61
  • 70
  • 2
    Duplicate: http://stackoverflow.com/questions/106896/how-many-python-classes-should-i-put-in-one-file/107836#107836 – S.Lott Jul 07 '09 at 11:27

6 Answers6

73

Here are some possible reasons:

  1. Python is not exclusively class-based - the natural unit of code decomposition in Python is the module. Modules are just as likely to contain functions (which are first-class objects in Python) as classes. In Java, the unit of decomposition is the class. Hence, Python has one module=one file, and Java has one (public) class=one file.
  2. Python is much more expressive than Java, and if you restrict yourself to one class per file (which Python does not prevent you from doing) you will end up with lots of very small files - more to keep track of with very little benefit.

An example of roughly equivalent functionality: Java's log4j => a couple of dozen files, ~8000 SLOC. Python logging => 3 files, ~ 2800 SLOC.

jpp
  • 159,742
  • 34
  • 281
  • 339
Vinay Sajip
  • 95,872
  • 14
  • 179
  • 191
21

There's a mantra, "flat is better than nested," that generally discourages an overuse of hierarchy. I'm not sure there's any hard and fast rules as to when you want to create a new module -- for the most part, people just use their discretion to group logically related functionality (classes and functions that pertain to a particular problem domain).

Good thread from the Python mailing list, and a quote by Fredrik Lundh:

even more important is that in Python, you don't use classes for every- thing; if you need factories, singletons, multiple ways to create objects, polymorphic helpers, etc, you use plain functions, not classes or static methods.

once you've gotten over the "it's all classes", use modules to organize things in a way that makes sense to the code that uses your components.
make the import statements look good.

Jimm Domingo
  • 203
  • 2
  • 9
cdleary
  • 69,512
  • 53
  • 163
  • 191
  • 1
    Loved the explanation for overuse of hierarchy part. Sometimes it is extremely hard to understand code when there is overuse of hierarchy in it. Especially when not well-documented, even a 'hello world' code becomes a headache – MuhsinFatih Aug 29 '17 at 09:08
7

the book Expert Python Programming has something related discussion
Chapter 4: Choosing Good Names:"Building the Namespace Tree" and "Splitting the Code"
My line crude summary: collect some related class to one module(source file),and collect some related module to one package, is helpful for code maintain.

sunqiang
  • 6,422
  • 1
  • 32
  • 32
5

In python, class can also be used for small tasks (just for grouping etc). maintaining a 1:1 relation would result in having too many files with small or little functionality.

Umair Ahmed
  • 11,238
  • 5
  • 33
  • 39
4

There is no specific convention for this - do whatever makes your code the most readable and maintainable.

RichieHindle
  • 272,464
  • 47
  • 358
  • 399
2

A good example of not having seperate files for each class might be the models.py file within a django app. Each django app may have a handful of classes that are related to that app, and putting them into individual files just makes more work.

Similarly, having each view in a different file again is likely to be counterproductive.

Matthew Schinckel
  • 35,041
  • 6
  • 86
  • 121
  • I disagree. By having more classes in one file you just exposing more classes to be affected by a circular dependency that maybe wouldn't even be an issue with them being in different files. But breaking groups up only when this happens makes an inconsistent codebase. – Győri Sándor Jan 28 '20 at 12:46
  • It depends. If you are talking about multiple models in a models.py, then you shouldn't be importing other model files in the global scope anyway (which is a sure-fire way in olden days to a circular dependency: IIRC django won't even allow it now due to a check). – Matthew Schinckel Feb 01 '20 at 12:20