1

I wrote a simple command-line tool in Python. To simplify the logic, I use a dict for storing the commands and handlers, something like this:

#!/usr/bin/env python

# some code here

DISPACHERS = {
    "run": func_run
    "list": func_list
}

# other code

The problem is, I have to put this piece of code after the function declarations, which is not the standard practice I have seen in other languages (i.e. constants in one block, variables after, and then the functions).

I could use strings for storing the function, and retrieve it using something like getattr(__main__, "func_run"), so I can stick with my preference, but I wonder if that's a "proper" way.

Any idea?

=== Update ===

Since it's a simple python script that handles some automation tasks of another project, so it would be better to keep it in a single file (no other module) if possible.

Lin
  • 620
  • 7
  • 11
  • Could you put them in different module then import them at the top of your script? Why can't it go at the top in its current state? – Holloway Jan 26 '16 at 12:43
  • @Holloway I don't think so, since it still misses the function declaration. Same reason, I cannot put it at the top since the actual handler functions are declared after it, or I'll have this error: `NameError: name 'func_run' is not defined` – Lin Jan 26 '16 at 12:54
  • Put it after the function declarations and don't make problem. – furas Jan 26 '16 at 13:01
  • 1
    What you are attempting to do is not standard practice in Python, so why have an artificial constraint just because other languages do it differently. Other languages do lots of things differently to Python - but that's their problem. – cdarke Jan 26 '16 at 13:03
  • 2
    Use Python as it's built to be used. For example, a costant variable or private method, as used in other language contexts, don't exist Python. And what Holloway meant was to put the functions `func_run` and `func_list` in a different file and then in your main you can simply do `from another_file import func_run, func_list` so that `DISPATCHERS` can then follow it right after. But if you really insist on side-stepping Python's natural (and elegant way) of scripting, have a look [here](http://stackoverflow.com/questions/1590608/is-it-possible-to-forward-declare-a-function-in-python). – Reti43 Jan 26 '16 at 14:46
  • When programming in language X, there should be no expectation that following the "standard practice ... in other languages" is the standard (or best, or even good) approach. In many cases, it may be a very poor approach, or may even be impossible (e.g. a standard object oriented practice taken from Smalltalk isn't going to fly very far if you're learning COBOL). Corollary: Python isn't Pascal. – twalberg Jan 26 '16 at 19:35
  • Yes, I understand this, that's why I am asking this question since I am not sure what I am doing is pythonic. – Lin Jan 27 '16 at 09:15

1 Answers1

2

Use a decorator to enumerate the functions.

dispatchmap = {}

def dispatcher(name):
  def add_dispatcher(func):
    dispatchmap[name] = func
    return func
  return add_dispatcher

 ...

@dispatcher('run')
def func_run(...):
   ...
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358