2015-01-16 5 views
3

у меня есть вопрос в питона, если кто-то может пожалуйста помочь Вот пример, у меня есть contextmanager нижеПолучить список функций, определенных в contextmanager с заявлением в питона

from contextlib import contextmanager 

@contextmanager 
def main_func(name): 
    print("<%s>" % name) 
    yield 
    print("</%s>" % name) 
    # Retreive the list of function here : tag_func1 and tag_func2 then run the one I need to run 

затем использовать его как ниже

with main_func("h1"): 
    def tag_func1(): 
     print("foo1") 

    def tag_func2(): 
     print("foo2") 

Я хотел бы знать, можно извлечь список функций, определенных в заявлении с здесь tag_func1 и tag_func1 в d запускать их динамически в коде.

мне нужно выполнить эти действия в функцию main_func, реализующего contextmanager

Большое спасибо вам помочь,

+2

Нет, это не то, что делают менеджеры контекста. Они определяют поведение только при входе и выходе из блока; они не имеют никакого доступа или контроля над тем, что происходит внутри блока. См. [Этот вопрос] (http://stackoverflow.com/questions/21248103/is-it-possible-to-access-the-context-object-code-block-inside-the-exit-m) и [этот ] (http://stackoverflow.com/questions/20767038/is-it-possible-to-access-enclosing-context-manager). – BrenBarn

+0

Контекстные менеджеры даже не создают отдельную область, поэтому все, что вы определяете внутри, также локально определяется вне нее. – poke

ответ

0
class ContextManager(): 

    def __init__(self): 
     self.functions = [] 

    def func(self, f): 
     self.functions.append(f) 
     return f 

    def __enter__(self): 
     return self 

    def __exit__(self, exc_type, exc_val, exc_tb): 
     for f in self.functions: 
      print(f.__name__) 


with ContextManager() as cm: 

    @cm.func 
    def add(x, y): 
     return x + y 

    def foo(): 
     return "foo" 

    @cm.func 
    def subtract(x, y): 
     return x - y 


# this code prints "add" and "subtract" 

Этот пользовательский менеджер контекста имеет доступ ко всем функциям, определенных внутри из с заявлением, которое украшено методом func.

+0

Отлично, похоже, это решение даже лучше, чем то, что я хотел сделать. Я проверю это сейчас. Большое спасибо - – skullomania

+0

Протестировано, и он отлично работает с моим классом. Еще раз спасибо. Просто быстрый, есть ли способ использовать другое имя, которое cm.func? cm.go (пример :)) – skullomania

+0

Разумеется, просто измените 'def func (self, f)' на 'def go (self, f)' в 'class ContextManager'. Если мой ответ решит вашу проблему, примите его (нажмите галочку), чтобы другие пользователи с этой проблемой знали, что мое решение работает. –