Давайте посмотрим на конкретный случай, который вы моделируете.Вы хотите связать функцию (несколько функций!) Со строковым именем, которое передается как sys.argv[1]
.В python самый удобный способ связать строки - это dict
!Ваш код может выглядеть примерно так:
# main.py:
import functions
function_map = {
'function1': functions.function1,
'function2': functions.function2,
'function3': functions.function3,
}
def main():
filename = sys.argv[1]
result = function_map[sys.argv[2]](filename)
# do something with result
# function.py contains all the functions:
def function1(filename):
# ...
Хорошо, так что этого достаточно, чтобы избавиться от getattr()
, но, возможно, мы можем сделать немного больше.Некоторые из этих функций, вероятно, имеют общий код;Держу пари, что большинство из них пытаются открыть файл, хотя могут быть и такие, которые этого не делают.Теперь мы приближаемся к тому, что может быть полезно для занятий!Вы по-прежнему можете обрабатывать объекты так же, как обычные функции, определяя метод __call__
.
class OpenFileFunctor(object):
def __init__(self, mode='rb'):
self.mode = mode
def __call__(self, filename):
# do some stuff with self.foo and filename!
return open(filename, self.mode).read()
С другой стороны, вы можете просто не сказать, что сказать в теле функции.Вы можете использовать лямбда-выражение, чтобы сократить функцию до просто записи в dict.
# main.py:
import functions
import os
function_map = {
'function1': functions.function1,
'slurp_unviersal': functions.OpenFileFunctor('rU'),
'is_text_file': (lambda fn: fn.lower().endswith(".txt") and os.path.isfile(fn)),
}