Пройдите через ряд функций в Python - PullRequest
3 голосов
/ 16 мая 2010

У меня есть неизвестное количество функций в моем скрипте Python (ну, это известно, но не постоянно), которые начинаются с сайта _... Мне было интересно, есть ли способ пройти через все эти функции в какой-то основной функции, которая их вызывает. что-то вроде:

foreach function_that_has_site_ as coolfunc
   if coolfunc(blabla,yada) == true:
      return coolfunc(blabla,yada)

так что они пройдут через все, пока не получат что-то истинное.

спасибо!

Ответы [ 6 ]

5 голосов
/ 16 мая 2010

Модуль inspect, уже упоминавшийся в других ответах, особенно удобен, потому что вы легко можете фильтровать имена и значения объектов, которые вас интересуют. inspect.getmembers принимает два аргумента: объект, члены которого вы исследуете, и предикат (функция, возвращающая bool), который примет (возвратит) True для) только те объекты, которые вас интересуют.

Чтобы получить «объект, который является этим модулем», вам нужна следующая известная идиома:

import sys
this_module = sys.modules[__name__]

В вашем предикате вы хотите выбрать только объекты, которые являются функциями и имеют имена, начинающиеся с site_:

import inspect
def function_that_has_site(f):
    return inspect.isfunction(f) and f.__name__.startswith('site_')

С этими двумя предметами ваша петля становится:

for n, coolfunc in inspect.getmembers(this_module, function_that_has_site):
   result = coolfunc(blabla, yada)
   if result: return result

Я также разделил тело цикла так, чтобы каждая функция вызывалась только один раз (что экономит время и - более безопасный подход, избегая возможных побочных эффектов) ... а также переписывая его в Python ; -)

3 голосов
/ 16 мая 2010

Вы пробовали использовать модуль проверки?

http://docs.python.org/library/inspect.html

Следующие методы будут возвращены:

inspect.getmembers

Тогда вы можете вызвать с помощью:

methodobjToInvoke = getattr(classObj, methodName) 
methodobj("arguments") 
1 голос
/ 16 мая 2010

Лучше всего использовать декоратор для перечисления функций, которые вам нужны:

_funcs = []

def enumfunc(func):
  _funcs.append(func)
  return func

@enumfunc
def a():
  print 'foo'

@enumfunc
def b():
  print 'bar'

@enumfunc
def c():
  print 'baz'

if __name__ == '__main__':
  for f in _funcs:
    f()
1 голос
/ 16 мая 2010
def run():
    for f_name, f in globals().iteritems():
        if not f_name.startswith('site_'):
            continue
        x = f()
        if x:
            return x
1 голос
/ 16 мая 2010

Этот метод просматривает все свойства текущего модуля и выполняет все функции, которые он находит с именем, начинающимся с site_:

import sys
import types
for elm in dir():
    f = getattr(sys.modules[__name__], elm)
    if isinstance(f, types.FunctionType) and f.__name__[:5] == "site_":
        f()

Проверка типа функции не требуется, если только имена функций имеют имена, начинающиеся с site_.

0 голосов
/ 16 мая 2010

Попробуйте dir(), globals() или locals(). Или проверить модуль (как упомянуто выше).

def site_foo():
  pass

def site_bar():
  pass

for name, f in globals().items():
  if name.startswith("site_"):
    print name, f()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...