9

I am writing a flask application, and I have found I have have ton of generic utility functions.

Here are the examples of the type of functions that I consider generic utility functions:

def make_hash():
  return defaultdict(make_hash)

def file_read(filename):
  with open(file_name_, 'r') as f:
    return f.read()

def file_write(filename, data):
  with open(filename, 'w') as f:
    f.write(data)

I was thinking of tossing these functions into a separate module all together. However, I am curious if I have the following concerns:

  • There are two few unique functions to warrant a separate module all together. i.e. the file_read, and file_write functions above could go into a file.py module, however since its two functions, I feel like this might be overkill.
  • In my application I use these functions 2-3 times per function so I am moving under the guise they creating these utility functions should help me save some lines of code, and hopefully is making me more efficient.

Question: - What would be the pythonic way of grouping generic utility functions? Should I create a separate module? Curious what others are doing for organizing this type of code.

fr00z1
  • 519
  • 5
  • 16

3 Answers3

2

I don't think it has much relation to Python, it's more a design decision.

For only these lines I would not make a separate module; however, if you use it 2 to 3 times I would not copy the code. If you later want to change something only one change is needed, keeping functionality consistent.

Also the methods seem to be very generic, so you could easily use them in other projects later.

And I assume you want to make them static (@static_method).

What I mostly do is group generic utility classes by type, i.e. in your case one file for dictionaries (having 1 method) and one for file (having 2 methods). Later possibly more methods will be added but the functionality is grouped by type/usage.

Jeff Widman
  • 22,014
  • 12
  • 72
  • 88
Michel Keijzers
  • 15,025
  • 28
  • 93
  • 119
  • 1
    This makes sense. I was reluctant to put this in a class only because I have (maybe an incorrect) pre-conceived notion of only creating classes for application specific items. However, I think I am going to make a hybrid using the solution you provided above.. i.e. utility package with a file/dictionary module. The grouping you provided above seems sound to me, and as you stated, I can grow these modules as I make more generic functions, and I can port these around. Also, I will most likely make these independent of the application. Thanks for the feedback. – fr00z1 Apr 29 '13 at 09:27
  • 3
    Why "classes" and "static_methods" ? Python is not Java, when all you need is a function then by all means use a function. – bruno desthuilliers Apr 29 '13 at 10:47
  • @user2152283 Yes it's best to make them application independent, it saves you work for every future project you are using the made functionality. – Michel Keijzers Apr 29 '13 at 11:08
  • @bruno desthuilliers: classes: because a class can be seen as a self contained set of functionality, in this case: Dictionary (utilities) and File (utilities). Static, because you do not want to make an instance to call a function... See the Utility Class (design pattern). – Michel Keijzers Apr 29 '13 at 11:10
0

In python we have something called Package (a usual folder with an empty file called __init__.py) this is used to contain all of your modules this way we create somesort of name spacing.

your application can access to its own name space using .

for example have the following files

MyPackage/__init__.py (empty)
MyPackage/webapp.py (your web application)
MyPackage/utils.py (generic utilities)

and in webapp.py you can have something like this

from .utils import *

or list them one by one

from .utils import file_read, file_write

pay attention to the dot prefix before utils

Muayyad Alsadi
  • 1,506
  • 15
  • 23
  • 6
    import * is generally considered to be a bad practice – Kiro Apr 29 '13 at 09:21
  • @Kiro, in general you are right, but in such specific case it's ok, because utils.py it's where he is going to place common function like his version of php's file_get_contents. if you are conserned you may define ```__all__``` – Muayyad Alsadi Apr 29 '13 at 09:27
  • Thank you for this response. This is a great answer, and I plan to use a variant of this solution. – fr00z1 Apr 29 '13 at 09:30
  • 6
    @muayyadalsadi: star imports are still a bad practice - they make code harder to understand (you have to open utils.py to know what symbols you import), and adding a new symbol in utils.py can potentially shadow an existing symbol in the modules where you star import from it. – bruno desthuilliers Apr 29 '13 at 10:45
  • the idea of the answer is how to pack utils inside his own name space, not to star import things. I've update my answer to show how to import specific functions – Muayyad Alsadi Apr 29 '13 at 11:02
0

There is something you can do to reduce the number of module files while retaining sub-categorisation of your modules.. Create multi-level module functions: myModule.Hash.<> myModule.FileIO.<>

This way you can import individual components as per your liking.

Vishal
  • 3,178
  • 2
  • 34
  • 47
  • Thank you for the feedback. I would have also marked this as an acceptable answer, just marking the above as the accepted answer since it was the first response. Thank you! – fr00z1 Apr 29 '13 at 09:28